我是靠谱客的博主 老实咖啡豆,这篇文章主要介绍python深度学习--dogs_vs_cat小量数据集训练,现在分享给大家,希望可以做个参考。

 首先注册kaggle并下载dogs-vs-cats数据集大概800M【最好使用科学上网,速度较快】,将其解压到指定路径(注意要逐层解压至文件夹形式)

#os.mkdir()为创建文件夹【执行一次后应当将其注释掉只留后面可能用到的一些路径配置】

复制代码
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
import numpy as np import pandas as pd import matplotlib.pyplot as plt import pylab from pandas import DataFrame, Series from keras import models, layers, optimizers, losses, metrics from keras.utils.np_utils import to_categorical import os,shutil #-------------数据划分------------------------------- # 原始数据集解压目录的路径 original_dataset_dir = 'F:/dogs-vs-cats/train/' #保存较小数据集的目录 base_dir = 'F:/dogs-vs-cats/cats_and_dogs_small' # os.mkdir(base_dir) ##分别对应划分后的训练、 验证和测试的目录 train_dir = os.path.join(base_dir, 'train') # os.mkdir(train_dir) validation_dir = os.path.join(base_dir, 'validation') # os.mkdir(validation_dir) test_dir = os.path.join(base_dir, 'test') # os.mkdir(test_dir) #猫的训练图像目录 train_cats_dir = os.path.join(train_dir, 'cats') # os.mkdir(train_cats_dir) #狗的训练图像目录 train_dogs_dir = os.path.join(train_dir, 'dogs') # os.mkdir(train_dogs_dir) #猫的验证图像目录 validation_cats_dir = os.path.join(validation_dir, 'cats') # os.mkdir(validation_cats_dir) # 狗的验证图像目录 validation_dogs_dir = os.path.join(validation_dir, 'dogs') # os.mkdir(validation_dogs_dir) # 猫的测试图像目录 test_cats_dir = os.path.join(test_dir, 'cats') # os.mkdir(test_cats_dir) # 狗的测试图像目录 test_dogs_dir = os.path.join(test_dir, 'dogs') # os.mkdir(test_dogs_dir) #将前 1000 张猫的图像复制 到 train_cats_dir # # fnames = ['cat.{}.jpg'.format(i) for i in range(1000)] # for fname in fnames: # src = os.path.join(original_dataset_dir, fname) # dst = os.path.join(train_cats_dir, fname) # shutil.copyfile(src, dst) # # #将接下来 500 张猫的图像复 制到 validation_cats_dir # fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)] # for fname in fnames: # src = os.path.join(original_dataset_dir, fname) # dst = os.path.join(validation_cats_dir, fname) # shutil.copyfile(src, dst) # # #将接下来的 500 张猫的图像 复制到 test_cats_dir # fnames = ['cat.{}.jpg'.format(i) for i in range(1500, 2000)] # for fname in fnames: # src = os.path.join(original_dataset_dir, fname) # dst = os.path.join(test_cats_dir, fname) # shutil.copyfile(src, dst) # # #将前 1000 张狗的图像复制 到 train_dogs_dir # fnames = ['dog.{}.jpg'.format(i) for i in range(1000)] # for fname in fnames: # src = os.path.join(original_dataset_dir, fname) # dst = os.path.join(train_dogs_dir, fname) # shutil.copyfile(src, dst) # # # 将接下来 500 张狗的图像复 制到 validation_dogs_dir # fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)] # for fname in fnames: # src = os.path.join(original_dataset_dir, fname) # dst = os.path.join(validation_dogs_dir, fname) # shutil.copyfile(src, dst) # # #将接下来 500 张狗的图像复 制到 test_dogs_dir # fnames = ['dog.{}.jpg'.format(i) for i in range(1500, 2000)] # for fname in fnames: # src = os.path.join(original_dataset_dir, fname) # dst = os.path.join(test_dogs_dir, fname) # shutil.copyfile(src, dst) #------------------------------------------------------ #每个分组中两个类别的样本数相同,这是一个平衡的二分类问题,分类精度可作为衡量成功的指标 #构建网络 #--------------------------------------- #卷积神经网络由 Conv2D 层(使用 relu 激活)和 MaxPooling2D 层交替堆叠构成 #由于这里要处理的是更大的图像和更复杂的问题,需要相应地增大网络,即再增 # 加一个 Conv2D+MaxPooling2D 的组合。 # 这既可以增大网络容量,也可以进一步减小特征图的尺寸, 使其在连接 Flatten # 层时尺寸不会太大。本例中初始输入的尺寸为 150×150(有些随意的选择),所 # 以最后在 Flatten 层之前的特征图大小为 7×7 #----------------------------------------- #注意 网络中特征图的深度在逐渐增大(从 32 增大到 128),而特征图的尺寸在逐渐减小(从 150×150 减小到 7×7)。这几乎是所有卷积神经网络的模式。 def model_build(): model = models.Sequential() model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(150, 150, 3))) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Conv2D(128, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Flatten()) model.add(layers.Dropout(0.5))#降低过拟合 model.add(layers.Dense(512, activation='relu')) model.add(layers.Dense(1, activation='sigmoid')) #二分类问题,你面对的是一个二分类问题,所以网络最后一层是使用 sigmoid 激活的单一单元(大小为 1 的 Dense 层)。输出为某一类的概率 print(model.summary()) #编译模型 model.compile(optimizer=optimizers.RMSprop(lr=1e-4), loss='binary_crossentropy', metrics=['acc']) return model #数据预处理 #--------------------------------------------------------- #将数据输入神经网络之前,应该将数据格式化为经过预处理的浮点数张量 #现在,数据以 JPEG 文件的形式保存在硬盘中,所以数据预处理步骤大致如下。 # (1) 读取图像文件。 # (2) 将 JPEG 文件解码为RGB像素网格。 # (3) 将这些像素网格转换为浮点数张量。 # (4) 将像素值(0~255 范围内)缩放到 [0, 1] 区间(正如你所知,神经网络喜欢处理较小的输入值)。 #Keras 拥有自动完成这些步骤的工具。 # Keras 有一个图像处理辅助工具的模块,位于 keras.preprocessing.image #特别地,它包含 ImageDataGenerator 类,可以快速创建 Python生成器, # 能够将硬盘上的图像文件自动转换 为预处理好的张量批量。 #--------------------------------------------------------- from keras.preprocessing.image import ImageDataGenerator def model_fit1(model): train_datagen=ImageDataGenerator(rescale=1./255)#将所有图像乘以 1/255 缩放至[0,1] test_datagen=ImageDataGenerator(rescale=1./255) train_generator=train_datagen.flow_from_directory( train_dir, target_size=(150,150),#将所有图像的大小调整为 150×150 batch_size=20, class_mode='binary'#因为使用了 binary_crossentropy,损失,所以需要用二进制标签 ) validation_generator=test_datagen.flow_from_directory( validation_dir, target_size=(150,150), batch_size=20, class_mode='binary' ) ''' Python 生成器(Python generator)是一个类似于迭代器的对象,一个可以和 for ... in 运算符一起使用的对象。生成器是用 yield 运算符来构造的。 下面一个生成器的例子,可以生成整数。 def generator(): i=0 while True: i += 1 yield i for item in generator(): print(item) if item > 4: break 输出结果如下。 1/n 2/n 3/n 4/n 5/n ''' for data_batch,labels_batch in train_generator: print(data_batch.shape) print(labels_batch.shape) break#生成器会不停地生成这些批量,它会不断循环目标文件夹中的图像 #它生成了 150×150 的 RGB 图像[形状为 (20, 150, 150,3)]与二进制标签[形状为 (20,)]组成的批量。每个批量中包含 20 个样本(批量大小) #下面我们利用生成器,我们让模型对数据进行拟合 #fit_generator 方法来拟合,它在数据生成器上的效果和 fit 相同 history=model.fit_generator( train_generator, steps_per_epoch=100, #从生成器中抽取 steps_per_epoch个批量后(即运行了 steps_per_epoch #次梯度下降),拟合过程将进入下一个轮次[本例共有1000+1000个样本, # 前面训练数据生成器的batch=20,故这里为100] epochs=30, validation_data=validation_generator, #参数可以是一个数据生成器,但也可以是 Numpy 数组组成的元组 #如果参数为生成器,那么这个生成器会不停地生成验证数据批量, # 因此还需要指定 validation_steps 参数与前面类似500+500 /20 validation_steps=50 ) #保存模型 model.save('cats_and_dogs_small_1.h5') return history def acc_loss_plot(history): fig=plt.figure() ax1=fig.add_subplot(2,1,1) acc = history.history['acc'] val_acc = history.history['val_acc'] loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(1, len(acc) + 1) ax1.plot(epochs, acc, 'bo', label='Training acc') ax1.plot(epochs, val_acc, 'b', label='Validation acc') ax1.set_title('Training and validation accuracy') ax2=fig.add_subplot(2,1,2) ax2.plot(epochs, loss, 'bo', label='Training loss') ax2.plot(epochs, val_loss, 'b', label='Validation loss') ax2.set_title('Training and validation loss') plt.legend() plt.tight_layout() plt.show() #训练精度随着时间线性增加,直到接近 100%,而验 证精度则停留在 70%~72%。验证损失仅在 5 轮后就达到最小值,然后保持不变,而训练损失则 一直线性下降,直到接近于 0 #因为训练样本相对较少(2000个),所以最关心的问题是过拟合。这里不使用dropout 和权重衰减(L2 正则化等,而是针对计算机视觉领域的新方法-----数据增强 #利用ImageDataGenerator设置数据增强 #数据增强 #------------------------------------------------------ # 是从现有的训练样本中生成更多的训练数据,其方法是利用多种能够生成可信图像的随机变换来增加(augment)样本。其目标是,模型在训练时不会两次查看完全相同的图像。这让模型能够观察到数据的更多内容,从而具有更好的泛化能力。 ''' datagen=ImageDataGenerator( rotation_range=40,#角度值(0-180),图像随机旋转的角度范围 width_shift_range=0.2,#图像水平方向平移范围(相对于总宽度的比例),下面同理 height_shift_range=0.2, shear_range=0.2,#随机错切变换的角度 zoom_range=0.2,#随机缩放的范围 horizontal_flip=True,#随机将一半图像水平翻转。如果没有水平不对称的假设(比如真实世界的图像),这种做法是有意义的。 fill_mode='nearest'#填充新创建像素的方法,这些新像素可能来自于旋转或宽度/高度平移 ) from keras.preprocessing import image fnames=[os.path.join(train_cats_dir,fname) for fname in os.listdir(train_cats_dir)]#获取猫的训练集数据路径 img_path=fnames[3] img=image.load_img(img_path,target_size=(150,150))#读取图像并调整大小 x=image.img_to_array(img)#将其转换为形状 (150, 150, 3) 的 Numpy 数组 x=x.reshape((1,)+x.shape)#将其形状改变为(1, 150, 150, 3) i=0 fig2=plt.figure() for batch in datagen.flow(x, batch_size=1):#生成随机变换后的图像批量。4个 ax=fig2.add_subplot(2,2,i+1) imgplot = ax.imshow(image.array_to_img(batch[0])) i += 1 if i % 4 == 0: break plt.show() ''' #如果你使用这种数据增强来训练一个新网络,那么网络将不会 # 两次看到同样的输入。但网络看到的输入仍然是高度相关的 # ,因为这些输入都来自于少量的原始图像。你无法生成新信 # 息, 而只能混合现有信息。因此,这种方法可能不足以完全 # 消除过拟合。 # 为了进一步降低过拟合,你还需要向模型中添加一个 # Dropout 层,添加到密集连接分类器之前 #-------------------------------------------------------- #利用数据增强生成器训练卷积神经网络 def model_fit2(model,train_dir,validation_dir): train_datagen=ImageDataGenerator( rescale=1./255, rotation_range=40, width_shift_range=0.2, height_shift_range=0.2, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, fill_mode='nearest'#默认 ) test_datagen=ImageDataGenerator(rescale=1./255)#注意,不能增强验证数据 train_generator=train_datagen.flow_from_directory( train_dir, target_size=(150,150),#将所有图像的大小调整为 150×150 batch_size=32, class_mode='binary'#因为使用了 binary_crossentropy,损失,所以需要用二进制标签 ) validation_generator=test_datagen.flow_from_directory( validation_dir, target_size=(150,150), batch_size=32, class_mode='binary' ) history = model.fit_generator( train_generator, steps_per_epoch=100, epochs=100, validation_data=validation_generator, validation_steps=50 ) model.save('cats_and_dogs_small_2.h5') return history # model=model_build() # history=model_fit2(model,train_dir,validation_dir) # acc_loss_plot(history)#得到了82%的精度,并且模型不再过拟合:训练曲线紧紧跟随着验证曲线

 ###未使用数据增强的卷积神经网络的训练和验证集精确度及损失图像

 

使用数据增强及dropout正则化后的图像

最后

以上就是老实咖啡豆最近收集整理的关于python深度学习--dogs_vs_cat小量数据集训练的全部内容,更多相关python深度学习--dogs_vs_cat小量数据集训练内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部