TypeError: function takes exactly 1 argument (3 given)

wsy: <p><span class="hashtag">#Why</span> is this error occurred when inputting gray image ？</p>
<h2>Reshape image in 3 dimensions (height = 28px, width = 28px, canal = 1)</h2>
<p>train_x= train.values.reshape(-1, 28, 28, 1).astype(‘uint8’)<br>
#train_x= np.stack((train_x,)*3, axis=-1)<br>
val_x = val.values.reshape(-1, 28, 28, 1).astype(‘uint8’)<br>
#val_x= np.stack((val_x,)*3, axis=-1)<br>
test_x = test.values.reshape(-1, 28, 28, 1).astype(‘uint8’)<br>
#test_x= np.stack((test_x,)*3, axis=-1)</p>
<h1>training 時做 data augmentation</h1>
<p>train_transform = transforms.Compose([transforms.ToPILImage(),<span class="hashtag">#一个现在还理解不了的操作</span><br>
transforms.RandomHorizontalFlip(),<span class="hashtag">#随机将图片水平翻转</span><br>
transforms.RandomRotation(15),<span class="hashtag">#随机旋转图片</span>，15<br>
transforms.ToTensor(),<span class="hashtag">#将图片转成tensor</span>，并把数值normalize到[0,1](data normalization),这里最后为啥还要加个，<br>
])</p>
<p>test_transform=transforms.Compose([transforms.ToPILImage(),<br>
transforms.ToTensor(),<br>
])</p>
<p>class ImgDataset(Dataset):<br>
def <strong>init</strong>(self,x,y=None,transform=None):<br>
self.x=x<br>
<span class="hashtag">#label</span> is required to be a Longtensor<br>
self.y=y<br>
if y is not None:<br>
self.y =torch.LongTensor(y)<br>
self.transform =transform<br>
def <strong>len</strong>(self):<br>
return len(self.x)<br>
def <strong>getitem</strong>(self,index):<br>
X=self.x[index]<br>
if self.transform is not None:<br>
X=self.transform(X)<br>
if self.y is not None:<br>
Y =self.y[index]<br>
return X,Y<br>
else:<br>
return X</p>
<p>batch_size = 128<br>
train_set=ImgDataset(train_x,train_y,train_transform)<br>
val_set = ImgDataset(val_x,val_y,test_transform)<br>
train_loader=DataLoader(train_set,batch_size=batch_size,shuffle=True)<br>
val_loader=DataLoader(val_set,batch_size=batch_size,shuffle=False)</p>

ptrblck: <p>Which line of code raises this error?<br>
Could you post the complete error message including the stack trace?</p>
<p>Also, please post code snippets by wrapping them into three backticks ```, as it’s easier to debug. <img src="https://discuss.pytorch.org/images/emoji/apple/wink.png?v=9" title=":wink:" class="emoji" alt=":wink:"></p>

wsy: <p>OK, thank you.Here is my error message and code，the error is reported in class imgdataset (dataset).<br>
‘’’<br>
for i,data in enumerate(train_loader):<br>
File “D:\ml\lib\site-packages\torch\utils\data\dataloader.py”, line 345, in <strong>next</strong><br>
data = self._next_data()<br>
File “D:\ml\lib\site-packages\torch\utils\data\dataloader.py”, line 385, in _next_data<br>
data = self._dataset_fetcher.fetch(index)  # may raise StopIteration<br>
File “D:\ml\lib\site-packages\torch\utils\data_utils\fetch.py”, line 44, in fetch<br>
data = [self.dataset[idx] for idx in possibly_batched_index]<br>
File “D:\ml\lib\site-packages\torch\utils\data_utils\fetch.py”, line 44, in <br>
data = [self.dataset[idx] for idx in possibly_batched_index]<br>
File “D:/梦/第四学期/ML/kaggle/digit recognizer/ditre.py”, line 70, in <strong>getitem</strong><br>
X=self.transform(X)<br>
File “D:\ml\lib\site-packages\torchvision\transforms\transforms.py”, line 70, in <strong>call</strong><br>
img = t(img)<br>
File “D:\ml\lib\site-packages\torchvision\transforms\transforms.py”, line 1003, in <strong>call</strong><br>
return F.rotate(img, angle, self.resample, self.expand, self.center, self.fill)<br>
File “D:\ml\lib\site-packages\torchvision\transforms\functional.py”, line 729, in rotate<br>
return img.rotate(angle, resample, expand, center, fillcolor=fill)<br>
File “D:\ml\lib\site-packages\PIL\Image.py”, line 1915, in rotate<br>
fillcolor=fillcolor)<br>
File “D:\ml\lib\site-packages\PIL\Image.py”, line 2205, in transform<br>
im = new(self.mode, size, fillcolor)<br>
File “D:\ml\lib\site-packages\PIL\Image.py”, line 2375, in new<br>
return Image()._new(core.fill(mode, size, color))<br>
TypeError: function takes exactly 1 argument (3 given)<br>
‘’’<br>
import os<br>
import numpy as np<br>
import cv2<br>
import torch<br>
import torch.nn as nn<br>
import torchvision.transforms as transforms<br>
import pandas as pd<br>
from torch.utils.data import DataLoader, Dataset<br>
import time</p>
<p>train = pd.read_csv(‘train.csv’)<br>
test = pd.read_csv(‘test.csv’)</p>
<p><span class="hashtag">#获取分类数</span></p>
<h1>label_gp = train.groupby(‘label’)</h1>
<h1>class_num = len(label_gp.count())</h1>
<p><span class="hashtag">#切分数据集</span><br>
train = train[:int(len(train)*0.7)]<br>
val = train[int(len(train)*0.7):]</p>
<h1>train_x = torch.from_numpy(train.iloc[:,1:].values)</h1>
<p>train_y = train.iloc[:,0].values.astype(‘uint8’)</p>
<h1>val_x =torch.from_numpy(val.iloc[:,1:].values)</h1>
<p>val_y =val.iloc[:,0].values.astype(‘uint8’)</p>
<h1>test_x = torch.from_numpy(test.values)</h1>
<p><span class="hashtag">#将数据集转化为图片的矩阵格式</span><br>
<span class="hashtag">#先去除label这一列</span><br>
train = train.drop(labels = [‘label’],axis=1)<br>
val = val.drop(labels = [‘label’],axis=1)</p>
<h2>Normalize the data</h2>
<h1>train = train / 255.0</h1>
<h1>val = val /255.0</h1>
<h1>test = test / 255.0</h1>
<h2>Reshape image in 3 dimensions (height = 28px, width = 28px, canal = 1)</h2>
<p>train_x= train.values.reshape(-1, 28, 28, 1).astype(‘uint8’)<br>
#train_x= np.stack((train_x,)*3, axis=-1)<br>
val_x = val.values.reshape(-1, 28, 28, 1).astype(‘uint8’)<br>
#val_x= np.stack((val_x,)*3, axis=-1)<br>
test_x = test.values.reshape(-1, 28, 28, 1).astype(‘uint8’)<br>
#test_x= np.stack((test_x,)*3, axis=-1)</p>
<h1>training 時做 data augmentation</h1>
<p>train_transform = transforms.Compose([transforms.ToPILImage(),<span class="hashtag">#一个现在还理解不了的操作</span><br>
transforms.RandomHorizontalFlip(),<span class="hashtag">#随机将图片水平翻转</span><br>
transforms.RandomRotation(15),<span class="hashtag">#随机旋转图片</span>，15<br>
transforms.ToTensor(),<span class="hashtag">#将图片转成tensor</span>，并把数值normalize到[0,1](data normalization),这里最后为啥还要加个，<br>
])</p>
<h1>testing 時不需做 data augmentation,为什么testing不需要？</h1>
<p>test_transform=transforms.Compose([transforms.ToPILImage(),<br>
transforms.ToTensor(),<br>
])</p>
<p>class ImgDataset(Dataset):<br>
def <strong>init</strong>(self,x,y=None,transform=None):<br>
self.x=x<br>
<span class="hashtag">#label</span> is required to be a Longtensor<br>
self.y=y<br>
if y is not None:<br>
self.y =torch.LongTensor(y)<br>
self.transform =transform<br>
def <strong>len</strong>(self):<br>
return len(self.x)<br>
def <strong>getitem</strong>(self,index):<span class="hashtag">#干啥的啊</span><br>
X=self.x[index]<br>
if self.transform is not None:<br>
X=self.transform(X)<br>
if self.y is not None:<br>
Y =self.y[index]<br>
return X,Y<br>
else:<br>
return X</p>
<p>batch_size = 128<br>
train_set=ImgDataset(train_x,train_y,train_transform)<br>
val_set = ImgDataset(val_x,val_y,test_transform)<br>
train_loader=DataLoader(train_set,batch_size=batch_size,shuffle=True)<br>
val_loader=DataLoader(val_set,batch_size=batch_size,shuffle=False)<span class="hashtag">#验证集是打不打乱的没啥意义吗</span></p>
<p>class Classifier(nn.Module):<br>
def <strong>init</strong>(self):<br>
super(Classifier,self).<strong>init</strong>()<br>
# torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)<br>
# torch.nn.MaxPool2d(kernel_size, stride, padding)<br>
# input 維度 [1, 28, 28]<br>
self.cnn = nn.Sequential(<br>
<span class="hashtag">#nn</span>.Conv2d(3,64,3,1,1),# [64,28,28]<span class="hashtag">#h</span>/w = (h/w - kennel_size + 2padding) / stride + 1<br>
nn.Conv2d(1, 28, 3, 1, 1),  # [64,28,28]<span class="hashtag">#h</span>/w = (h/w - kennel_size + 2padding) / stride + 1</p>
<pre><code>        # in_channels：输入维度,out_channels：输出维度,kernel_size：卷积核大小,stride：步长大小,padding：补1
           nn.BatchNorm2d(64),#在卷积神经网络的卷积层之后总会添加BatchNorm2d进行数据的归一化处理，
        # 这使得数据在进行Relu之前不会因为数据过大而导致网络性能的不稳定
            nn.ReLU(),
            nn.MaxPool2d(2,2,0),#[64,14,14]

            nn.Conv2d(64,128,3,1,1),#[128,14,14]
            nn.BatchNorm2d(128),
            nn.ReLU(),
            nn.MaxPool2d(2,2,0),#[128,7,7]

            nn.Conv2d(128, 256, 3, 1, 1),  # [256, 7, 7]
            nn.BatchNorm2d(256),
            nn.ReLU(),
            nn.MaxPool2d(2, 2, 0),  # [256, 4, 4]
            #
            # nn.Conv2d(256, 512, 3, 1, 1),  # [512, 16, 16]
            # nn.BatchNorm2d(512),
            # nn.ReLU(),
            # nn.MaxPool2d(2, 2, 0),  # [512, 8, 8]
            #
            # nn.Conv2d(512, 512, 3, 1, 1),  # [512, 8, 8]
            # nn.BatchNorm2d(512),
            # nn.ReLU(),
            # nn.MaxPool2d(2, 2, 0),  # [512, 4, 4]
</code></pre>
<p>)</p>
<pre><code>    self.fc = nn.Sequential(
        nn.Linear(256*4*4,1024),
        nn.ReLU(),
        nn.Linear(1024,512),
        nn.ReLU(),
        nn.Linear(512,10),#分成10类
</code></pre>
<p>)<br>
<span class="hashtag">#。。。忘了forward是干啥的了</span><br>
def forward(self,x):<br>
out = self.cnn(x)<br>
out = out.view(out.size()[0],-1)<span class="hashtag">#这个reshape有啥意义</span><br>
return self.fc(out)</p>
<h1></h1>
<h1>batch_size = 128</h1>
<h1>train_set = TensorDataset(train_x,train_y)</h1>
<h1>val_set = TensorDataset(val_x,val_y)</h1>
<h1>train_loader=DataLoader(train_set,batch_size=batch_size,shuffle=True)</h1>
<h1>val_loader=DataLoader(val_set,batch_size=batch_size,shuffle=False)</h1>
<h1></h1>
<p>model = Classifier().cpu()<br>
loss  = nn.CrossEntropyLoss()# 因為是 classification task，所以 loss 使用 CrossEntropyLoss<br>
optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # optimizer 使用 Adam<br>
num_epoch = 30<br>
<span class="hashtag">#使用</span> training set 訓練，並使用 valid   ation set 尋找好的參數<br>
for epoch in range(num_epoch):<br>
epoch_start_time = time.time()<br>
train_acc=0.0<br>
train_loss = 0.0<br>
val_acc = 0.0<br>
val_loss=0.0</p>
<pre><code>model.train()# 确保 model 是在 train model (开放 Dropout 等...)
for i,data in enumerate(train_loader):
    optimizer.zero_grad()
    train_pred = model(data[0].cpu())#data[0]是X,data[1]是Y
    batch_loss =loss(train_pred,data[1].cpu())
    batch_loss.backward()
    optimizer.step()  # 以 optimizer 用 gradient 更新參數值?干啥的来着

    train_acc += np.sum(np.argmax(train_pred.cpu().data.numpy(), axis=1) == data[1].numpy())#啥意思啊，train_acc += np.sum(np.argmax(train_pred.cpu().data.numpy(), axis=1) == data[1].numpy())
    train_loss+= batch_loss.item()

model.eval()
with torch.no_grad():
    for i,data in enumerate(val_loader):
        val_pred = model(data[0].cpu())
        batch_loss = loss(val_pred,data[1])

        val_acc+= np.sum(np.argmax(val_pred.cpu().data.numpy(),axis=1)==data[1].numpy())
        val_loss+=batch_loss.item()
    #将结果rint出来
    print('[%03d/%03d] %2.2f sec(s) Train Acc: %3.6f Loss: %3.6f | Val Acc: %3.6f loss: %3.6f' % \
              (epoch + 1, num_epoch, time.time() - epoch_start_time, \
               train_acc / train_set.__len__(), train_loss / train_set.__len__(), val_acc / val_set.__len__(),
               val_loss / val_set.__len__()))
</code></pre>
<p>‘’’</p>

ptrblck: <p>The error seems to be raised by <code>PIL</code>, so I would recommend to update it and also <code>torchvision</code>, if you are not using the latest stable version.</p>