整体文件目录结构如下:
--------dataset
|---------train
|---------01
|---------01.jpg
|---------02.jpg
|---------0....jpg
|---------0n.jpg
|---------02
|---------01.jpg
|---------02.jpg
|---------0....jpg
|---------0n.jpg
|---------03
|---------01.jpg
|---------02.jpg
|---------0....jpg
|---------0n.jpg
|---------test
|---------01
|---------01.jpg
|---------02.jpg
|---------0....jpg
|---------0n.jpg
|---------02
|---------01.jpg
|---------02.jpg
|---------0....jpg
|---------0n.jpg
|---------03
|---------01.jpg
|---------02.jpg
|---------0....jpg
|---------0n.jpg
下面放一个神经网络最基本的结构:
import os,shutil
import tensorflow
from tensorflow.keras import models
from tensorflow.keras import layers
from tensorflow.keras import optimizers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
# 数据集
train_dir = './任务1/train' # 训练集目录
test_dir = './任务1/test' # 测试集目录
print('train_0_images:', len(os.listdir(os.path.join(train_dir, '0'))))
print('train_1_images:', len(os.listdir(os.path.join(train_dir, '1'))))
print('train_2_images:', len(os.listdir(os.path.join(train_dir, '2'))))
print('test_0_images:', len(os.listdir(os.path.join(test_dir, '0'))))
print('test_1_images:', len(os.listdir(os.path.join(test_dir, '1'))))
print('test_2_images:', len(os.listdir(os.path.join(test_dir, '2'))))
model = models.Sequential()
model.add(layers.Conv2D(32,(3,3),activation='relu',padding='same',input_shape=((28,28,1))))
model.add(layers.MaxPool2D(2,2))
# model.add(layers.Conv2D(64,(3,3),activation='relu'))
# model.add(layers.MaxPool2D(2,2))
# model.add(layers.Conv2D(128,(3,3),activation='relu'))
# model.add(layers.MaxPool2D(2,2))
# # model.add(layers.Conv2D(128,(3,3),activation='relu'))
# # model.add(layers.MaxPool2D(2,2))
model.add(layers.Flatten())
# model.add(layers.Dense(8,activation = 'relu'))
model.add(layers.Dense(3,activation="softmax"))
model.summary()
# 选择优化器
model.compile(loss='categorical_crossentropy',#binary_crossentropy二分类
optimizer=optimizers.RMSprop(lr=1e-4),
metrics=['acc'])
#数据预处理
#这里不理解可以看一下博客里面的相关的一篇文章
train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)
# 它生成了 150×150 的 RGB 图像
#[形状为 (20, 150, 150, 3)]
#与二进制标签[形状为 (20,)]组成的批量
train_generator = train_datagen.flow_from_directory(
train_dir,
target_size=(28,28),
batch_size=20,
color_mode='grayscale',
class_mode='categorical'#这个地方二分类是binary,多分类是categorical
)
validation_generator = test_datagen.flow_from_directory(
test_dir,
target_size=(28,28),#target_size=(28,28),这里生成的图像是(28,28,3),但实际上我们的图像只有1通道
color_mode='grayscale',
batch_size=20,
class_mode='categorical'
)
# 利用批量生成器拟合模型
# steps_per_epoch 参数的作用:从生成器中抽取
# steps_per_epoch 个批量后拟合过程
# 每个批量包含 20 个样本,所以读取完所有 2000 个样本需要 100个批量
# validation_steps:需要从验证生成器中抽取多少个批次用于评估
history = model.fit_generator(
train_generator,
steps_per_epoch=100,
epochs=20,
validation_data=validation_generator,
validation_steps=20)
#保存模型
model.save('./任务1/small_data_1.h5')
# 绘制训练过程中的损失曲线和精度曲线
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)
plt.plot(epochs,acc,'bo',label='Training acc')
plt.plot(epochs,val_acc,'b',label='validation acc')
plt.title('train and validation acc')
plt.legend()
plt.figure()
plt.plot(epochs,loss,'bo',label='Training loss')
plt.plot(epochs,val_loss,'b',label='val_loss acc')
plt.title('train and validation loss')
plt.legend()
plt.show()
在设计神经网络层数的时候最好计算一下,否则可能会报错
ImageDataGenerator类的简单介绍:
通过实时数据增强生成张量图像数据批次,并且可以循环迭代,我们知道在Keras中,当数据量很多的时候我们需要使用model.fit_generator()方法,该方法接受的第一个参数就是一个生成器。简单来说就是:ImageDataGenerator()是keras.preprocessing.image模块中的图片生成器,可以每一次给模型“喂”一个batch_size大小的样本数据,同时也可以在每一个批次中对这batch_size个样本数据进行增强,扩充数据集大小,增强模型的泛化能力。比如进行旋转,变形,归一化等等。
总结起来就是两个点:
(1)图片生成器,负责生成一个批次一个批次的图片,以生成器的形式给模型训练;
(2)对每一个批次的训练图片,适时地进行数据增强处理(data augmentation);
详细的这个类的内容可以查看这篇文章,是我转载过来的我觉得不错的一篇文章:https://blog.csdn.net/qq_36654309/article/details/111029695