TypeError: function takes exactly 1 argument (3 given)

#Why is this error occurred when inputting gray image ?

Reshape image in 3 dimensions (height = 28px, width = 28px, canal = 1)

train_x= train.values.reshape(-1, 28, 28, 1).astype(‘uint8’)
#train_x= np.stack((train_x,)*3, axis=-1)
val_x = val.values.reshape(-1, 28, 28, 1).astype(‘uint8’)
#val_x= np.stack((val_x,)*3, axis=-1)
test_x = test.values.reshape(-1, 28, 28, 1).astype(‘uint8’)
#test_x= np.stack((test_x,)*3, axis=-1)

training 時做 data augmentation

train_transform = transforms.Compose([transforms.ToPILImage(),#一个现在还理解不了的操作
transforms.RandomHorizontalFlip(),#随机将图片水平翻转
transforms.RandomRotation(15),#随机旋转图片,15
transforms.ToTensor(),#将图片转成tensor,并把数值normalize到[0,1](data normalization),这里最后为啥还要加个,
])

test_transform=transforms.Compose([transforms.ToPILImage(),
transforms.ToTensor(),
])

class ImgDataset(Dataset):
def init(self,x,y=None,transform=None):
self.x=x
#label is required to be a Longtensor
self.y=y
if y is not None:
self.y =torch.LongTensor(y)
self.transform =transform
def len(self):
return len(self.x)
def getitem(self,index):
X=self.x[index]
if self.transform is not None:
X=self.transform(X)
if self.y is not None:
Y =self.y[index]
return X,Y
else:
return X

batch_size = 128
train_set=ImgDataset(train_x,train_y,train_transform)
val_set = ImgDataset(val_x,val_y,test_transform)
train_loader=DataLoader(train_set,batch_size=batch_size,shuffle=True)
val_loader=DataLoader(val_set,batch_size=batch_size,shuffle=False)

Which line of code raises this error?
Could you post the complete error message including the stack trace?

Also, please post code snippets by wrapping them into three backticks ```, as it’s easier to debug. :wink:

OK, thank you.Here is my error message and code,the error is reported in class imgdataset (dataset).
‘’’
for i,data in enumerate(train_loader):
File “D:\ml\lib\site-packages\torch\utils\data\dataloader.py”, line 345, in next
data = self._next_data()
File “D:\ml\lib\site-packages\torch\utils\data\dataloader.py”, line 385, in _next_data
data = self._dataset_fetcher.fetch(index) # may raise StopIteration
File “D:\ml\lib\site-packages\torch\utils\data_utils\fetch.py”, line 44, in fetch
data = [self.dataset[idx] for idx in possibly_batched_index]
File “D:\ml\lib\site-packages\torch\utils\data_utils\fetch.py”, line 44, in
data = [self.dataset[idx] for idx in possibly_batched_index]
File “D:/梦/第四学期/ML/kaggle/digit recognizer/ditre.py”, line 70, in getitem
X=self.transform(X)
File “D:\ml\lib\site-packages\torchvision\transforms\transforms.py”, line 70, in call
img = t(img)
File “D:\ml\lib\site-packages\torchvision\transforms\transforms.py”, line 1003, in call
return F.rotate(img, angle, self.resample, self.expand, self.center, self.fill)
File “D:\ml\lib\site-packages\torchvision\transforms\functional.py”, line 729, in rotate
return img.rotate(angle, resample, expand, center, fillcolor=fill)
File “D:\ml\lib\site-packages\PIL\Image.py”, line 1915, in rotate
fillcolor=fillcolor)
File “D:\ml\lib\site-packages\PIL\Image.py”, line 2205, in transform
im = new(self.mode, size, fillcolor)
File “D:\ml\lib\site-packages\PIL\Image.py”, line 2375, in new
return Image()._new(core.fill(mode, size, color))
TypeError: function takes exactly 1 argument (3 given)
‘’’
import os
import numpy as np
import cv2
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import pandas as pd
from torch.utils.data import DataLoader, Dataset
import time

train = pd.read_csv(‘train.csv’)
test = pd.read_csv(‘test.csv’)

#获取分类数

label_gp = train.groupby(‘label’)

class_num = len(label_gp.count())

#切分数据集
train = train[:int(len(train)*0.7)]
val = train[int(len(train)*0.7):]

train_x = torch.from_numpy(train.iloc[:,1:].values)

train_y = train.iloc[:,0].values.astype(‘uint8’)

val_x =torch.from_numpy(val.iloc[:,1:].values)

val_y =val.iloc[:,0].values.astype(‘uint8’)

test_x = torch.from_numpy(test.values)

#将数据集转化为图片的矩阵格式
#先去除label这一列
train = train.drop(labels = [‘label’],axis=1)
val = val.drop(labels = [‘label’],axis=1)

Normalize the data

train = train / 255.0

val = val /255.0

test = test / 255.0

Reshape image in 3 dimensions (height = 28px, width = 28px, canal = 1)

train_x= train.values.reshape(-1, 28, 28, 1).astype(‘uint8’)
#train_x= np.stack((train_x,)*3, axis=-1)
val_x = val.values.reshape(-1, 28, 28, 1).astype(‘uint8’)
#val_x= np.stack((val_x,)*3, axis=-1)
test_x = test.values.reshape(-1, 28, 28, 1).astype(‘uint8’)
#test_x= np.stack((test_x,)*3, axis=-1)

training 時做 data augmentation

train_transform = transforms.Compose([transforms.ToPILImage(),#一个现在还理解不了的操作
transforms.RandomHorizontalFlip(),#随机将图片水平翻转
transforms.RandomRotation(15),#随机旋转图片,15
transforms.ToTensor(),#将图片转成tensor,并把数值normalize到[0,1](data normalization),这里最后为啥还要加个,
])

testing 時不需做 data augmentation,为什么testing不需要?

test_transform=transforms.Compose([transforms.ToPILImage(),
transforms.ToTensor(),
])

class ImgDataset(Dataset):
def init(self,x,y=None,transform=None):
self.x=x
#label is required to be a Longtensor
self.y=y
if y is not None:
self.y =torch.LongTensor(y)
self.transform =transform
def len(self):
return len(self.x)
def getitem(self,index):#干啥的啊
X=self.x[index]
if self.transform is not None:
X=self.transform(X)
if self.y is not None:
Y =self.y[index]
return X,Y
else:
return X

batch_size = 128
train_set=ImgDataset(train_x,train_y,train_transform)
val_set = ImgDataset(val_x,val_y,test_transform)
train_loader=DataLoader(train_set,batch_size=batch_size,shuffle=True)
val_loader=DataLoader(val_set,batch_size=batch_size,shuffle=False)#验证集是打不打乱的没啥意义吗

class Classifier(nn.Module):
def init(self):
super(Classifier,self).init()
# torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
# torch.nn.MaxPool2d(kernel_size, stride, padding)
# input 維度 [1, 28, 28]
self.cnn = nn.Sequential(
#nn.Conv2d(3,64,3,1,1),# [64,28,28]#h/w = (h/w - kennel_size + 2padding) / stride + 1
nn.Conv2d(1, 28, 3, 1, 1), # [64,28,28]#h/w = (h/w - kennel_size + 2padding) / stride + 1

        # 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]

)

    self.fc = nn.Sequential(
        nn.Linear(256*4*4,1024),
        nn.ReLU(),
        nn.Linear(1024,512),
        nn.ReLU(),
        nn.Linear(512,10),#分成10类

)
#。。。忘了forward是干啥的了
def forward(self,x):
out = self.cnn(x)
out = out.view(out.size()[0],-1)#这个reshape有啥意义
return self.fc(out)

batch_size = 128

train_set = TensorDataset(train_x,train_y)

val_set = TensorDataset(val_x,val_y)

train_loader=DataLoader(train_set,batch_size=batch_size,shuffle=True)

val_loader=DataLoader(val_set,batch_size=batch_size,shuffle=False)

model = Classifier().cpu()
loss = nn.CrossEntropyLoss()# 因為是 classification task,所以 loss 使用 CrossEntropyLoss
optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # optimizer 使用 Adam
num_epoch = 30
#使用 training set 訓練,並使用 valid ation set 尋找好的參數
for epoch in range(num_epoch):
epoch_start_time = time.time()
train_acc=0.0
train_loss = 0.0
val_acc = 0.0
val_loss=0.0

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__()))

‘’’

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