机器学习笔记(二十五)——Tensorflow 2(多分类)

本博客仅用于个人学习,不用于传播教学,主要是记自己能够看得懂的笔记(

学习知识来自:【吴恩达团队Tensorflow2.0实践系列课程第一课】TensorFlow2.0中基于TensorFlow2.0的人工智能、机器学习和深度学习简介及基础编程_哔哩哔哩_bilibili

多分类其实我们也做过了,包括老师也说很简单。比如人与马的程序,我们改成辨别石头剪刀布的程序。

首先,要把数据集改成多分类,用三个目录装三个不同类别的数据。然后将ImageDataGenerator的导入分类模式改为'categorical',神经网络最后一层Dense改为3个神经元,激活函数改为'softmax'。最后,将compile里面的Loss函数改为'categorical_crossentropy'。

基本就这些啦。

数据:train_data:

https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps.zip

test_data:

https://storage.googleapis.com/laurencemoroney-blog.appspot.com/rps-test-set.zip

代码:

from tensorflow.keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator as idg
import tensorflow as tf
import numpy as np
import os
from tensorflow.keras.optimizers import RMSprop

class myCallback(tf.keras.callbacks.Callback): #Callback类的继承类
    def on_epoch_end(self,epoch,logs={}): #重写on_epoch_end函数
        if logs.get('val_loss')<10 and logs.get('val_accuracy')>0.80:
            print('\nReached 80% accuracy so canceling training.')
            self.model.stop_training=True #达到条件,停止训练

callback=myCallback()
filepath=os.path.abspath(__file__) #获取本文件的绝对路径
filepath=os.path.dirname(filepath) #获取本文件的父目录
files=[]
for root,dirs,files in os.walk(filepath+'/tmp/rps-test-set'): #获取rps-test-set目录下的所有文件名
    used_up_variable=0

datagen=idg( #此处为增强数据的各种方法
    rescale=1./255, #归一化
    rotation_range=40, #随机旋转-40~40度
    width_shift_range=0.2, #随机改变宽度20%
    height_shift_range=0.2, #随机改变高度20%
    shear_range=0.2, #随机倾斜裁剪20%
    zoom_range=0.2, #随机放大20%
    horizontal_flip=True, #随机翻转
    fill_mode='nearest' #图像改变后,需要将像素重新填充,用最近像素的特征来填充
) #数据增强的generator
traingen=datagen.flow_from_directory( #训练数据集,并用文件夹名作为标签分类
    filepath+'/tmp/rps', #数据集所在地址
    target_size=(150,150), #自动生成150*150的图片
    batch_size=10, #这个不能太大,不然会超内存,所以我这个程序运行得贼慢
    class_mode='categorical' #多分类模式
)
valigen=datagen.flow_from_directory( #验证数据集
    filepath+'/tmp/rps-vali-set',
    target_size=(150,150),
    batch_size=10,
    class_mode='categorical'
)

model=tf.keras.Sequential([
    tf.keras.layers.Conv2D(16,(3,3),activation='relu',input_shape=(150,150,3)),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Conv2D(32,(3,3),activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Conv2D(64,(3,3),activation='relu'),
    tf.keras.layers.MaxPooling2D(2,2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(512,activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(3,activation='softmax')
])

model.compile(
    optimizer=RMSprop(lr=0.0001), #新型优化器
    loss='categorical_crossentropy', #多分类交叉熵
    metrics=['accuracy']
)
print(model.summary())

model.fit( #训练模型
    traingen, #训练数据集generator
    steps_per_epoch=252, #注意前面的batch_size,这两个乘起来要大于等于数据集个数
    epochs=15,
    validation_data=valigen, #验证数据集generator
    validation_steps=38, #这个与验证数据集的batch_size也是一样,乘起来大于等于验证数据集个数
    callbacks=[callback]
)

for file in files:
    pat=filepath+'/tmp/rps-test-set/'+file
#    img=cv2.imdecode(np.fromfile(pat,dtype=np.uint8),-1)
    img=image.load_img(pat,target_size=(150,150)) #导入图像
    x=image.img_to_array(img) #变成array类
    imgs=np.expand_dims(x,axis=0) #增加一个维度

#    imgs=np.vstack([imgs])
#    imgs=imgs/255.0 #归一化
    classes=model.predict(imgs,batch_size=10)
    print(file)
    print(classes[0]) #输出预测值

得到结果:

paper01.png
[0. 0. 1.]
paper02.png
[1. 0. 0.]
paper03.png
[0. 0. 1.]
paper04.png
[1. 0. 0.]
paper05.png
[1. 0. 0.]
rock01.png
[0. 1. 0.]
rock02.png
[0. 1. 0.]
rock03.png
[0. 1. 0.]
rock04.png
[0. 1. 0.]
rock05.png
[0. 1. 0.]
scissors01-00.png
[0. 0. 1.]
scissors01-26.png
[0. 0. 1.]
scissors02-00.png
[0. 0. 1.]
scissors02-30.png
[0. 0. 1.]
scissors03-00.png
[0. 0. 1.]
scissors03-30.png
[0. 0. 1.]
scissors04-00.png
[0. 0. 1.]
scissors04-30.png
[0. 0. 1.]

还不错啦。

posted @ 2021-08-16 17:50  Lcy的瞎bb  阅读(349)  评论(0编辑  收藏  举报