【问题记录】pytorch自定义数据集 No such file or directory, invalid index of a 0-dim
保存模型:
:
保存整個神經網絡的結構和模型參數
torch.save(mymodel, ‘mymodel.pkl’)
只保存神經網絡的模型參數
torch.save(mymodel.state_dict(), ‘mymodel_params.pkl’)
導入模型:
mymodel = torch.load(‘mymodel.pkl’)
x=x.view(1,1,4,5) 意思是將 x 矩陣轉換成 (1,1,4,5) 的四維矩陣,第一個 1是樣本數,第二個1是通道數,第三個 4 和第四個 5 是高度和寬度。
卷積層
卷積層是用一個固定大小的矩形區去席卷原始數據,將原始數據分成一個個和卷積核大小相同的小塊,然后將這些小塊和卷積核相乘輸出一個卷積值(注意:這里是一個單獨的值,不再是矩陣了)。
conv2d 是二維度卷積,對數據在寬度和高度兩個維度上進行卷積。
函數:
torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups)
weight:卷積核權重,也就是卷積核本身,是一個四維度數組,(out_channels, in_channels/groups, kH, kW
Out_channels)。
out_channels是卷積核輸出層的神經元個數,也就是這層有多少個卷積核,;in_channels 輸入通道數,kH kW是卷積核的高度和寬
第一個代碼:
train_hd=pandas.read_csv('C:\\Users\\number.csv') train_path='C:\\Users\\pic'class Mydataset(Dataset):def __init__(self,df_data,data_dir='./',transform=None):super().__init__()self.df=df_data.valuesself.data_dir=data_dirself.transform=transformdef __len__(self):return len(self.df)def __getiem__(self,idex):c,img_name,label=self.df[idex]img_path=os.path.join(self.data_dir,img_name)image=cv2.imread(img_path)if self.transform is not None:image=self.transform(image)return image,labeltransforms_train=transforms.Compose([transforms.ToPILImage(),transforms.RandomHorizontalFlip(),transforms.RandomRotation(10),transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])train_data=Mydataset(train_hd,train_path,transform=transforms_train) BATCH_SIZE=64 train_loader=DataLoader(train_data,batch_size=BATCH_SIZE,shuffle=True) print(train_data.__len__()) print(train_data.__getiem__(100)) # --------------------------------------------------------hidden_layer = 3 input_data = 3 output_data = 2 x = Variable(torch.randn(BATCH_SIZE, input_data), requires_grad= False) y = Variable(torch.randn(BATCH_SIZE, output_data), requires_grad =False) w1 = Variable(torch.randn(input_data, hidden_layer) , requires_grad= True) w2 = Variable(torch.randn(hidden_layer, output_data) , requires_grad =True) epochn = 100 # grad.data. zero() 全部置零, learning_rate = 1e-6 for epoch in range(epochn):y_pred = x.mm(w1).clamp(min=0).mm(w2)loss = (y_pred - y).pow(2).sum()print("Epoch:{},Loss:{:.4f}".format(epoch,loss.item()))loss.backward()w1.data -= learning_rate * w1.grad.dataw2.data -= learning_rate * w2.grad.dataw1.grad.data.zero_()w2.grad.data.zero_()之后的代碼:
import torch.nn.functional as Fimport torch import torch.nn as nn from torch.autograd import Variablefrom torchvision import transforms from torch.utils.data.dataset import Dataset from torch.utils.data.dataloader import DataLoader from PIL import Imageimport torch.optim as optim import os# ***************************初始化一些函數******************************** # torch.cuda.set_device(gpu_id)#使用GPU learning_rate = 0.0001 # 學習率的設置# *************************************數據集的設置**************************************************************************** root = os.getcwd() + '/data/' # 數據集的地址# 定義讀取文件的格式 def default_loader(path):return Image.open(path).convert('RGB')class MyDataset(Dataset):# 創建自己的類: MyDataset,這個類是繼承的torch.utils.data.Dataset# ********************************** #使用__init__()初始化一些需要傳入的參數及數據集的調用**********************def __init__(self, txt, transform=None, target_transform=None):super(MyDataset, self).__init__()# 對繼承自父類的屬性進行初始化imgs = []fh = open("./data/num.txt", 'r')# 按照傳入的路徑和txt文本參數,以只讀的方式打開這個文本for line in fh: # 迭代該列表#按行循環txt文本中的內line = line.strip('\n')line = line.rstrip('\n')# 刪除 本行string 字符串末尾的指定字符,這個方法的詳細介紹自己查詢pythonwords = line.split()# 用split將該行分割成列表 split的默認參數是空格,所以不傳遞任何參數時分割空格imgs.append((words[0], int(words[1])))# 把txt里的內容讀入imgs列表保存,具體是words幾要看txt內容而定# 很顯然,根據我剛才截圖所示txt的內容,words[0]是圖片信息,words[1]是lableself.imgs = imgsself.transform = transformself.target_transform = target_transform# *************************** #使用__getitem__()對數據進行預處理并返回想要的信息**********************def __getitem__(self, index): # 這個方法是必須要有的,用于按照索引讀取每個元素的具體內容fn, label = self.imgs[index]print(fn+'mm')# fn是圖片path #fn和label分別獲得imgs[index]也即是剛才每行中word[0]和word[1]的信息img_path = os.path.join("C:/Users/pic/", fn)img = Image.open(img_path).convert('RGB')# 按照路徑讀取圖片if self.transform is not None:img = self.transform(img)# 數據標簽轉換為Tensorreturn img, label# return回哪些內容,那么我們在訓練時循環讀取每個batch時,就能獲得哪些內容# ********************************** #使用__len__()初始化一些需要傳入的參數及數據集的調用**********************def __len__(self):# 這個函數也必須要寫,它返回的是數據集的長度,也就是多少張圖片,要和loader的長度作區分return len(self.imgs)class Net(nn.Module): # 定義網絡,繼承torch.nn.Moduledef __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(1, 6, 5) # 卷積層self.pool = nn.MaxPool2d(2, 2) # 池化層self.conv2 = nn.Conv2d(6, 16, 5) # 卷積層self.fc1 = nn.Linear(16 * 5 * 5, 120) # 全連接層self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 2) # 2個輸出def forward(self, x): # 前向傳播x = self.pool(F.relu(self.conv1(x))) # F就是torch.nn.functionalx = self.pool(F.relu(self.conv2(x)))x = x.view(-1, 16 * 5 * 5) # .view( )是一個tensor的方法,使得tensor改變size但是元素的總數是不變的。# 從卷基層到全連接層的維度轉換x = F.relu(self.fc1(x))x = F.relu(self.fc2(x))x = self.fc3(x)returnnet = Net() # 初始化一個卷積神經網絡leNet- train_data = MyDataset(txt=root + 'num.txt', transform=transforms.Compose([transforms.Resize((32, 32)),# 將圖片縮放到指定大小(h,w)或者保持長寬比并縮放最短的邊到int大小transforms.CenterCrop(32),transforms.ToTensor()]))train_loader = DataLoader(dataset=train_data, batch_size=2, shuffle=True) # batch_size:從樣本中取多少張,每一次epoch都會輸入batch_size張 print('num_of_trainData:', len(train_data))def trainandsave():# 神經網絡結構print('h')net = Net()optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) # 學習率為0.001criterion = nn.CrossEntropyLoss() # 損失函數也可以自己定義,我們這里用的交叉熵損失函數# 訓練部分i = 0for epoch in range(5): # 訓練的數據量為5個epoch,每個epoch為一個循環# 每個epoch要訓練所有的圖片,每訓練完成200張便打印一下訓練的效果(loss值)running_loss = 0.0 # 定義一個變量方便我們對loss進行輸出for i, data in enumerate(train_loader, 0): # 這里我們遇到了第一步中出現的trailoader,代碼傳入數據# enumerate是python的內置函數,既獲得索引也獲得數據# get the inputsinputs, labels = data # data是從enumerate返回的data,包含數據和標簽信息,分別賦值給inputs和labels# wrap them in Variableinputs, labels = Variable(inputs), Variable(labels) # # 轉換數據格式用Variableoptimizer.zero_grad() # 梯度置零,因為反向傳播過程中梯度會累加上一次循環的梯度# forward + backward + optimizeoutputs = net(inputs) # 把數據輸進CNN網絡netloss = criterion(outputs, labels) # 計算損失值loss.backward() # loss反向傳播optimizer.step() # 反向傳播后參數更新running_loss += loss.data[0] # loss累加if i % 20 == 19:print('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 20)) # 然后再除以200,就得到這兩百次的平均損失值running_loss = 0.0 # 這一個200次結束后,就把running_loss歸零,下一個200次繼續使用print('Finished Training')# 保存神經網絡torch.save(net, 'net.pkl')# 保存整個神經網絡的結構和模型參數torch.save(net.state_dict(), 'net_params.pkl')if __name__ == '__main__':for i, data in enumerate(train_loader, 0):print(i)報錯信息:
發現每次batch_size修改后對迭代有影響。只有batch_size為1時才進入了main 的循環,很奇怪。然后 fp = builtins.open(filename, “rb”)
FileNotFoundError: [Errno 2] No such file or directory: ‘C:/Users/pic/a_236.jpg’
一直以為自己文件夾下面有圖片,但是仔細檢查才知道自己那部分圖片是png后綴結尾的,天哪,搗鼓了一下午居然就因為這個原因,我狂汗阿。。。。真的太不仔細了。。。。粗心害死人。。。。。
但是我也產生了疑問,難道pytorch的訓練圖片只能說jpg格式嗎?在書上也沒看到過這一點。
另一個報錯:
TypeError: pic should be Tensor or ndarray. Got <class ‘PIL.Image.Image’>.
方法:刪去transform的toPILIMAGE。
用程序將png后綴文件改成jpg之后仍然有錯:
看來文件已經都能迭代成功了,但是參數有問題。
發現在net中的第一卷積層是這樣的:
self.conv1 = nn.Conv2d(2, 6, 5) # 卷積層
這個函數第一個參數為輸入的通道數,第二個參數為輸出的通道數。而我圖片是3通道
改為:
self.conv1 = nn.Conv2d(3, 6, 5) # 卷積層
之后的報錯:
loss.data[0] # loss累加
IndexError: invalid index of a 0-dim
版本原因,應該把data[0]寫成.item()
修改所有錯誤終于開始訓練了:
上面結果的全部代碼:
記住net的前向傳播函數要return x
總結
以上是生活随笔為你收集整理的【问题记录】pytorch自定义数据集 No such file or directory, invalid index of a 0-dim的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【笔记】spring的注解回顾,spri
- 下一篇: 【笔记】JAVA中的泛型和反射