卷积神经网络实战一 水果分类

主要环境配置

win10,pycharm
Python3.6
keras2.2.0
numpy1.16.0
pillow8.1.1
scipy1.5.4
tensorflow-gpu1.11.0
先使用自己的配置,没有问题的话就不用更改

数据介绍

Fruits 360
A dataset with 90483 images of 131 fruits and vegetables
每张图片:100x100,真彩(3通道)

数据获取

数据来自于网上公开数据集
https://www.kaggle.com/moltean/fruits

或者,数据及源码:(源码包括两种方式编写的经典卷积神经网络LeNet-5模型)
链接:https://pan.baidu.com/s/1iKSZTu4cPM8d-VxnH4Xx8A
提取码:06wk

另外,人工智能入门四件套免费分享(统计学习方法、机器学习、机器学习实战、深度学习)
链接:https://pan.baidu.com/s/1kG3cRvto75krhjz1Ow4ANw 提取码:b8r1

库引用

import os
from skimage import io
import numpy as np
from sklearn.utils import shuffle
import keras
import tensorflow as tf

数据载入

原来的数据集有131种分类,为了节省训练时间方便学习,分别建了一个用于训练和测试的文件夹,把想要训练的分类从原数据文件夹拷到里面

dir_path1 = 'fruits-360/Training1'
dir_path2 = 'fruits-360/Test1'
#读取数据
def load_data(dir_path):
    images = []
    labels = []
    file = os.listdir(dir_path)  #返回一个列表:包含dir_path里的文件名,即分类
    n_classes = len(file)        #分类数量
    n = 0
    for l in file:
        img = os.listdir(dir_path+'/'+ l)
        for i in img:
            img_path = dir_path+'/'+ l+'/'+ i
            labels.append(int(n))
            images.append(io.imread(img_path))
        n += 1
    return images,labels,n_classes

images,labels,n_classes = load_data(dir_path1)
images_test,labels_test,_ = load_data(dir_path2)
print("种类:",n_classes)

数据预处理

仅进行数组化,打乱顺序,标签转换为独热编码

#数据预处理:
def data_processing(images,labels,n_classes):
    train_x = np.array(images)
    train_y = np.array(labels)
    indx = np.arange(0,train_y.shape[0])
    indx = shuffle(indx)       #随机打乱
    train_x = train_x[indx]
    train_y = train_y[indx]
    train_y = keras.utils.to_categorical(train_y,n_classes)  #转为Onehot标签
    return train_x,train_y

train_x,train_y = data_processing(images,labels,n_classes)
test_x,test_y = data_processing(images_test,labels_test,n_classes)

搭建模型

经典的卷积神经网络LeNet-5模型,使用全局平均池化层代替全连接层,并使用了高级库contrib简洁代码。即源码中的(4)。
神经网络参数配置

batch_size = 32
dropout = 0.8
training_epochs = 5
learningrate = 0.001

filter_height = 5
filter_width = 5

in_channels = 3
out_channels1 = 32
out_channels2 = 64

image_size = train_x.shape[1]  ##图片尺寸
total_data_num = train_x.shape[0]

stride1 = 2
stride2 = 2

x = tf.placeholder(tf.float32,[None,image_size,image_size,in_channels])
tf.summary.image('x',x,max_outputs=10)
y = tf.placeholder(tf.float32,[None,n_classes])
tf.summary.histogram('y',y)
keep_prob = tf.placeholder(tf.float32)

卷积神经网络结构搭建

def conv_net(x,dropout):
    ##卷积层1
    h_conv1 = tf.contrib.layers.conv2d(x,out_channels1,[filter_height,filter_width],1,'SAME',activation_fn=tf.nn.relu)
    h_pool1 = tf.contrib.layers.max_pool2d(h_conv1,[stride1,stride1],stride=stride1,padding='SAME')

    ##卷积层2
    h_conv2 = tf.contrib.layers.conv2d(h_pool1,out_channels2,[filter_height,filter_width],1,'SAME',activation_fn=tf.nn.relu)
    h_pool2 = tf.contrib.layers.max_pool2d(h_conv2, [stride2, stride2], stride=stride2, padding='SAME')

    ## Dropout(Dropout层防止预测数据过拟合)
    conv2 = tf.nn.dropout(h_pool2, dropout)

    ## 全局平均池化层
    avg_pool = tf.contrib.layers.conv2d(conv2,n_classes,[filter_height,filter_width],1,'SAME',activation_fn=tf.nn.relu)
    prediction = tf.contrib.layers.avg_pool2d(avg_pool, [25, 25], stride=25, padding='SAME')
    return tf.reshape(prediction, [-1, n_classes])

# 优化预测准确率
prediction = conv_net(x,keep_prob)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=prediction, labels=y))  ##交叉熵损失函数
tf.summary.scalar('loss_function',loss)
optimizer = tf.train.AdamOptimizer(learningrate).minimize(loss)  ##优化器

correct_pred = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
tf.summary.scalar('accuracy',accuracy)

保存模型

saver = tf.train.Saver()
savedir = 'log/model'

初始化会话并开始训练

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    merged_summary_op = tf.summary.merge_all()
    summary_writer = tf.summary.FileWriter('log/summaries',sess.graph)
    # 启动循环开始训练
    for epoch in range(training_epochs):
        total_batch = int(total_data_num / batch_size)
        # 遍历全部数据集
        for i in range(total_batch):
            batch_x, batch_y = train_x[i * batch_size:batch_size * (i + 1), :], train_y[
                                                                                i * batch_size:batch_size * (i + 1), :]
            _, acc, Loss = sess.run([optimizer, accuracy, loss], feed_dict={x: batch_x, y: batch_y, keep_prob: dropout})
            # Compute average loss
            print("Epoch:", '%04d' % (epoch + 1), "cost=", "{:.9f}".format(Loss), "Training accuracy",
                  "{:.5f}".format(acc))
        summary_str = sess.run(merged_summary_op,feed_dict={x: batch_x, y: batch_y, keep_prob: dropout})
        summary_writer.add_summary(summary_str,epoch)  #Tensorboard可视化
    print(" Finished!")
    saver.save(sess,'log/model')
    # 测试 model
    test_feed = {x: test_x[0:100], y: test_y[0:100], keep_prob: 1}
    print('Testing Accuracy:', sess.run(accuracy, feed_dict=test_feed))

运行结果

本次是进行了37种水果分类。
测试准确率
在这里插入图片描述
Tensorboard显示

节选输入图片

在这里插入图片描述
损失函数
在这里插入图片描述

载入模型使用

#载入模型
with tf.Session() as sess2:
    sess2.run(tf.global_variables_initializer())
    saver.restore(sess2,savedir)
    test_feed = {x: test_x[200:300], y: test_y[200:300], keep_prob: 1}
    print('Testing Accuracy:', sess2.run(accuracy, feed_dict=test_feed))

在这里插入图片描述
记录自己的学习之路,发现问题请不吝赐教,多多交流。

  • 16
    点赞
  • 136
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值