第一步先在kaggle注册账号密码(接受验证码需要翻墙!)
搜索10monkeys,下载数据集,数据集是已经分好类的文件夹。
注意目录:两个training
所以我们在调用训练集文件夹时候一定要打两次地址
train_dir = "input-monkeys/training/training"
valid_dir = "input-monkeys/validation/validation"
label_file = "input-monkeys/monkey_labels.txt"
然后用os这个包判断是否存在
#用os来判断路径是否存在
print(os.path.exists(train_dir))
print(os.path.exists(valid_dir))
print(os.path.exists(label_file))
编写读取数据的代码
用pd.read_csv API读取
labels是子文件夹到真正文件夹的映射
#指定哪一行作为表头。默认设置为0(即第一行作为表头),如果没有表头的话,要修改参数,设置header=None
labels = pd.read_csv(label_file,header = 0)
print(labels)
设置输入相同尺寸大小的图片:
#定义缩放后图片参数
height = 128
width = 128
channels = 3
batch_size = 64
num_classes = 10
tf.dataset用来读取数据,ImageDataGenerator用来读取图片数据
#ImageDataGenerator 帮助处理图片,rescale1/255,每个像素点/255-->(0,1)
#rotation_range:将图片随机旋转正负40度角度
#width_shift_range代表位移,增加位移鲁棒性,水平,height:竖直,小于1代表随机比例范围,大于1代表像素值
#shear_range:剪切强度,zoom_range:缩放强度
#horizonetal_flip:是否做水平翻转,fill_mode:是否操作后填充像素,“nearest"用附近的真实像素值填充。
train_datagen = keras.preprocessing.image.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',
)
如果targets函数是one-hot编码,用 categorical_crossentropy,one-hot 编码:[0, 0, 1], [1, 0, 0], [0, 1, 0]
如果tagets函数是数字编码 ,用 sparse_categorical_crossentropy,数字编码:2, 0, 1
#调取图片,并且按上方法处理(seed:随机数,shuffle:是否混排,class_mode:label的编码格式)
train_generator = train_datagen.flow_from_directory(train_dir,
target_size = (height,width),
batch_size =batch_size,
seed = 7,
shuffle =True,
class_mode = "categorical"
)
#在验证集很多操作不用毕竟只是做验证,但是缩放还是得做,做验证,没有必要混排
valid_datagen = keras.preprocessing.image.ImageDataGenerator(rescale = 1./255)
valid_generator = valid_datagen.flow_from_directory(valid_dir,
target_size = (height,width),
batch_size =batch_size,
seed = 7,
shuffle =False,
class_mode = "categorical"
)
看一下都有多少数据
train_num = train_generator.samples
valid_num = valid_generator.samples
print(train_num,valid_num)
下面从generator中取数据:
.next可以获得下一组数据
for i in range(2):
x,y = train_generator.next()
print(x.shape, y.shape)
print(y)
来定义模型:
# 类似,两个卷积加一个pooling
# !!!!!selu在全连接情况一般会起到一个很好的效果,但是卷积一般还是relu好一点
model = keras.models.Sequential([
keras.layers.Conv2D(filters=32, kernel_size=3, padding='same',
activation='relu', input_shape=[width, height, channels]),
keras.layers.Conv2D(filters=32, kernel_size=3, padding='same',
activation='relu'),
keras.layers.MaxPool2D(pool_size=2),
keras.layers.Conv2D(filters=64, kernel_size=3, padding='same',
activation='relu'),
keras.layers.Conv2D(filters=64, kernel_size=3, padding='same',
activation='relu'),
keras.layers.MaxPool2D(pool_size=2),
keras.layers.Conv2D(filters=128, kernel_size=3, padding='same',
activation='relu'),
keras.layers.Conv2D(filters=128, kernel_size=3, padding='same',
activation='relu'),
keras.layers.MaxPool2D(pool_size=2),
keras.layers.Flatten(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(num_classes, activation='softmax'),
])
model.compile(loss="categorical_crossentropy",
optimizer="adam", metrics=['accuracy'])
print(model.summary())
#epoch数目代表完整训练样本得数目,steps_per_epoch代表训练批次
epochs = 10
history = model.fit_generator(train_generator,
steps_per_epoch= train_num//batch_size,
epochs= epochs,
validation_data = valid_generator,
validation_steps = valid_num //batch_size
)
print(history.history.keys())
分开打印曲线
def plot_learning_curves(history,label,epochs,min_value,max_value):
data = {}
data[label] = history.history[label]
data['val_'+label] = history.history['val_'+label]
pd.DataFrame(data).plot(figsize = (8,5))
plt.grid(True)
plt.axis([0,epochs,min_value,max_value])
plt.show()
plot_learning_curves(history,'acc',epochs,0,1)
plot_learning_curves(history,'loss',epochs,1.5,2.5)