大部分的pytorch入门教程,都是使用torchvision里面的数据进行训练和测试。如果我们是自己的图片数据,又该怎么做呢?
一、我的数据
我在学习的时候,使用的是fashion-mnist。这个数据比较小,我的电脑没有GPU,还能吃得消。关于fashion-mnist数据,可以百度,也可以点此 了解一下,数据就像这个样子:
下载地址:https://github.com/zalandoresearch/fashion-mnist
但是下载下来是一种二进制文件,并不是图片,因此我先转换成了图片。
我先解压gz文件到e:/fashion_mnist/文件夹
然后运行代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
import os from skimage import io import torchvision.datasets.mnist as mnist root = "E:/fashion_mnist/" train_set = ( mnist.read_image_file(os.path.join(root, 'train-images-idx3-ubyte' )), mnist.read_label_file(os.path.join(root, 'train-labels-idx1-ubyte' )) ) test_set = ( mnist.read_image_file(os.path.join(root, 't10k-images-idx3-ubyte' )), mnist.read_label_file(os.path.join(root, 't10k-labels-idx1-ubyte' )) ) print ( "training set :" ,train_set[ 0 ].size()) print ( "test set :" ,test_set[ 0 ].size()) def convert_to_img(train = True ): if (train): f = open (root + 'train.txt' , 'w' ) data_path = root + '/train/' if ( not os.path.exists(data_path)): os.makedirs(data_path) for i, (img,label) in enumerate ( zip (train_set[ 0 ],train_set[ 1 ])): img_path = data_path + str (i) + '.jpg' io.imsave(img_path,img.numpy()) f.write(img_path + ' ' + str (label) + '\n' ) f.close() else : f = open (root + 'test.txt' , 'w' ) data_path = root + '/test/' if ( not os.path.exists(data_path)): os.makedirs(data_path) for i, (img,label) in enumerate ( zip (test_set[ 0 ],test_set[ 1 ])): img_path = data_path + str (i) + '.jpg' io.imsave(img_path, img.numpy()) f.write(img_path + ' ' + str (label) + '\n' ) f.close() convert_to_img( True ) convert_to_img( False ) |
这样就会在e:/fashion_mnist/目录下分别生成train和test文件夹,用于存放图片。还在该目录下生成了标签文件train.txt和test.txt.
二、进行CNN分类训练和测试
先要将图片读取出来,准备成torch专用的dataset格式,再通过Dataloader进行分批次训练。
代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
import torch from torch.autograd import Variable from torchvision import transforms from torch.utils.data import Dataset, DataLoader from PIL import Image root = "E:/fashion_mnist/" # -----------------ready the dataset-------------------------- def default_loader(path): return Image. open (path).convert( 'RGB' ) class MyDataset(Dataset): def __init__( self , txt, transform = None , target_transform = None , loader = default_loader): fh = open (txt, 'r' ) imgs = [] for line in fh: line = line.strip( '\n' ) line = line.rstrip() words = line.split() imgs.append((words[ 0 ], int (words[ 1 ]))) self .imgs = imgs self .transform = transform self .target_transform = target_transform self .loader = loader def __getitem__( self , index): fn, label = self .imgs[index] img = self .loader(fn) if self .transform is not None : img = self .transform(img) return img,label def __len__( self ): return len ( self .imgs) train_data = MyDataset(txt = root + 'train.txt' , transform = transforms.ToTensor()) test_data = MyDataset(txt = root + 'test.txt' , transform = transforms.ToTensor()) train_loader = DataLoader(dataset = train_data, batch_size = 64 , shuffle = True ) test_loader = DataLoader(dataset = test_data, batch_size = 64 ) #-----------------create the Net and training------------------------ class Net(torch.nn.Module): def __init__( self ): super (Net, self ).__init__() self .conv1 = torch.nn.Sequential( torch.nn.Conv2d( 3 , 32 , 3 , 1 , 1 ), torch.nn.ReLU(), torch.nn.MaxPool2d( 2 )) self .conv2 = torch.nn.Sequential( torch.nn.Conv2d( 32 , 64 , 3 , 1 , 1 ), torch.nn.ReLU(), torch.nn.MaxPool2d( 2 ) ) self .conv3 = torch.nn.Sequential( torch.nn.Conv2d( 64 , 64 , 3 , 1 , 1 ), torch.nn.ReLU(), torch.nn.MaxPool2d( 2 ) ) self .dense = torch.nn.Sequential( torch.nn.Linear( 64 * 3 * 3 , 128 ), torch.nn.ReLU(), torch.nn.Linear( 128 , 10 ) ) def forward( self , x): conv1_out = self .conv1(x) conv2_out = self .conv2(conv1_out) conv3_out = self .conv3(conv2_out) res = conv3_out.view(conv3_out.size( 0 ), - 1 ) out = self .dense(res) return out model = Net() print (model) optimizer = torch.optim.Adam(model.parameters()) loss_func = torch.nn.CrossEntropyLoss() for epoch in range ( 10 ): print ( 'epoch {}' . format (epoch + 1 )) # training----------------------------- train_loss = 0. train_acc = 0. for batch_x, batch_y in train_loader: batch_x, batch_y = Variable(batch_x), Variable(batch_y) out = model(batch_x) loss = loss_func(out, batch_y) train_loss + = loss.data[ 0 ] pred = torch. max (out, 1 )[ 1 ] train_correct = (pred = = batch_y). sum () train_acc + = train_correct.data[ 0 ] optimizer.zero_grad() loss.backward() optimizer.step() print ( 'Train Loss: {:.6f}, Acc: {:.6f}' . format (train_loss / ( len ( train_data)), train_acc / ( len (train_data)))) # evaluation-------------------------------- model. eval () eval_loss = 0. eval_acc = 0. for batch_x, batch_y in test_loader: batch_x, batch_y = Variable(batch_x, volatile = True ), Variable(batch_y, volatile = True ) out = model(batch_x) loss = loss_func(out, batch_y) eval_loss + = loss.data[ 0 ] pred = torch. max (out, 1 )[ 1 ] num_correct = (pred = = batch_y). sum () eval_acc + = num_correct.data[ 0 ] print ( 'Test Loss: {:.6f}, Acc: {:.6f}' . format (eval_loss / ( len ( test_data)), eval_acc / ( len (test_data)))) |
打印出来的网络模型:
训练和测试结果:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://www.cnblogs.com/denny402/p/7520063.html