Tensorflow框架搭建卷积神经网络进行五种花的分类

24 篇文章 11 订阅
20 篇文章 3 订阅

数据集:
五种花:daisy、dandelion、roses、sunflowers、tulips
在这里插入图片描述
数据集下载:http://download.tensorflow.org/example_images/flower_photos.tgz

读取并随机打乱数据集: read_img.py

# -*- coding: utf-8 -*-
"""
Created on Wed Jun 26 09:23:46 2019

@author: ZQQ
"""

import numpy as np
import os
import glob
from skimage import transform,io
import random

# 定义超参数
w = 100 
h = 100

#### 定义读取图片的函数:read_img()
def read_img(path):
    data_list = [path + x for x in os.listdir(path) if os.path.isdir(path + x)] # 所有图片分类目录
    imgs = [] # 定义一个imgs空列表,存放遍历读取的图片
    labels = [] # 定义一个labels空列表,存放图片标签
    for idx, folder in enumerate(data_list):  # 遍历每个文件夹中的图片,idx表示
        for im in glob.glob(folder + '/*.jpg'):  # *:匹配0个或多个字符
            print('reading the images:%s' % (im))
            img = io.imread(im)
            img = transform.resize(img, (w, h)) # 将所有图片的尺寸统一为:100*100(宽度*高度)
            with open('datasets_name.txt','a') as f:
                f.write(folder+im+'_'+str(idx)+'\n')
            imgs.append(img) # 遍历后更改尺寸后的图片添加到imgs列表中
            labels.append(idx) # 遍历后更改尺寸后的图片标签添加到labels列表中
    return np.asarray(imgs, np.float32), np.asarray(labels, np.int32) # np.float32是类型 后面两个变量是没有进行np.asarray

# np.asarray 和 np.array
# np.array与np.asarray功能是一样的,都是将输入转为矩阵格式。
# 主要区别在于 np.array(默认情况下)将会copy该对象,而 np.asarray除非必要,否则不会copy该对象。

### 定义随机打乱数据集的函数:shuffle_data()
def shuffle_data(data,label):
    # 打乱顺序
    data_size = data.shape[0] # 数据集个数
    arr = np.arange(data_size) # 生成0到datasize个数
    np.random.shuffle(arr) # 随机打乱arr数组
    data = data[arr] # 将data以arr索引重新组合
    label = label[arr] # 将label以arr索引重新组合
    
#    # 打乱数据顺序的另一种方法,当然还有其他的方法
#    index = [i for i in range(len(data))]
#    random.shuffle(index)
#    data = data[index]
#    label = label[index]
    
    # 将所有数据分为训练集和验证集
    ratio = 0.8 # 训练集比例
    num = np.int(len(data) * ratio)
    x_train = data[:num]
    y_train = label[:num]
    x_val = data[num:]
    y_val = label[num:]
    
    return x_train, y_train, x_val, y_val

#path = 'flower_photos/' # 所有图片的总路径(目录)
#data, label = read_img(path)

搭建卷积神经网络:cnn.py

# -*- coding: utf-8 -*-
"""
Created on Wed Jun 26 16:38:15 2019

@author: ZQQ

tools:Pycharm

用tensorflo框架搭建一个卷积神经网络
参考:
https://www.cnblogs.com/ansang/p/9164805.html

数据:http://download.tensorflow.org/example_images/flower_photos.tgz

"""

import tensorflow as tf

# 定义批量标准化函数,有效防止了梯度消失和爆炸,还加速了收敛
# def batch_norm(x, momentum=0.9, epsilon=1e-5, train=True, name='bn'):
#     return tf.layers.batch_normalization(x,
#                                          momentum=momentum,
#                                          epsilon=epsilon,
#                                          scale=True,
#                                          training=train,
#                                          name=name)

def simple_net(x):
    ### 卷积,池化
    # 第一层卷积层(100->50)
    conv1 = tf.layers.conv2d(inputs=x,
                             filters=32,
                             #kernel_size=[3,3], # kernel_size = [5,5] 换不同的核大小,查看效果
                             kernel_size = [5,5],
                             padding="same",
                             activation=tf.nn.relu,
                             kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))  # padding="same",卷积层不改变图片大小
    #conv1 = batch_norm(conv1, name="pw_bn1")  # 加入批量标准化
    pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2,2], strides=2) # 池化层图片大小缩小一半

    # 第二个卷积层(50->25)
    conv2 = tf.layers.conv2d(inputs=pool1,
                             filters=64,
                             kernel_size=[5,5],
                             padding="same",
                             activation=tf.nn.relu,
                             kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
    #conv2 = batch_norm(conv2, name="pw_bn2")
    pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2,2], strides=2)

    # 第三个卷积层(25->12)
    conv3 = tf.layers.conv2d(inputs=pool2,
                             filters=128,
                             kernel_size=[3,3],
                             padding="same",
                             activation=tf.nn.relu,
                             kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
    #conv3 = batch_norm(conv3, name="pw_bn3")
    pool3 = tf.layers.max_pooling2d(inputs=conv3,
                                    pool_size=[2,2],
                                    strides=2)

    # 第四个卷积层(12->6)
    conv4 = tf.layers.conv2d(inputs=pool3,
                             filters=128,
                             kernel_size=[3,3],
                             padding="same",
                             activation=tf.nn.relu,
                             kernel_initializer=tf.truncated_normal_initializer(stddev=0.01))
    #conv4 = batch_norm(conv4, name="pw_bn4")
    pool4 = tf.layers.max_pooling2d(inputs=conv4,
                                    pool_size=[2,2],
                                    strides=2)

    rel = tf.reshape(pool4,[-1, 6 * 6 * 128])

    # 防止过拟合,加入dropout
    #dropout = tf.layers.dropout(inputs=rel, rate=0.5)

    ### 全连接层
    dense1 = tf.layers.dense(inputs=rel,
                             units=1024,
                             activation=tf.nn.relu,
                             kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                             kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))

    dense2 = tf.layers.dense(inputs=dense1,
                             units=512,
                             activation=tf.nn.relu,
                             kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                             kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))

    logits = tf.layers.dense(inputs=dense2,
                             units=5, # 5个类
                             activation=None,
                             kernel_initializer=tf.truncated_normal_initializer(stddev=0.01),
                             kernel_regularizer=tf.contrib.layers.l2_regularizer(0.003))

    #pred = tf.nn.softmax(logits, name='prob') # softmax处理
    #return logits, pred
    return logits

### 四个卷积层,两个全连接层,一个softmax层组成。
### 在每一层的卷积后面加入batch_normalization, relu, 池化
### batch_normalization层很好用,加了它之后,有效防止了梯度消失和爆炸,还加速了收敛。

定义一个批量取数据的函数:batch_get_data.py

# -*- coding: utf-8 -*-
"""
Created on Wed Jun 26 21:23:56 2019

@author: ZQQ
"""

import numpy as np

# 定义一个函数,按批次取数据
def minibatches(inputs=None, targets=None, batch_size=None, shuffle=False):
    assert len(inputs) == len(targets)
    if shuffle:
        indices = np.arange(len(inputs))
        np.random.shuffle(indices)
    for start_idx in range(0, len(inputs) - batch_size + 1, batch_size):
        if shuffle:
            excerpt = indices[start_idx:start_idx + batch_size]
        else:
            excerpt = slice(start_idx, start_idx + batch_size)
        yield inputs[excerpt], targets[excerpt]

实验结果:
进行100次epoch
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:val loss 来看,有点过拟合,精度没有得到大的提高,后期加入dropout再进一步查看实验效果。
还可以进行批量标准化,加速收敛,并且可以防止梯度消失或者梯度爆炸。
以及加入softmax处理等。
独立测试:test_independent.py
训练得到模型保存后,加载,测试输入的图片

# -*- coding: utf-8 -*-
"""
Created on Sat Jun 29 14:57:15 2019

@author: ZQQ

参考:
https://www.cnblogs.com/ansang/p/9164805.html
"""

import numpy as np
import tensorflow as tf
from PIL import Image, ImageDraw, ImageFont
from models import cnn
import matplotlib.pyplot as plt

# 将所有的图片resize成100*100
w = 100
h = 100
c = 3

classes = ['daisy','dandelion','roses','sunflowers','tulips']
image_test = Image.open('flowers_photos_independent/test1.jpg')

plt.imshow(image_test)
plt.show()

resized_image = image_test.resize((w, h), Image.BICUBIC)
image_data = np.array(resized_image, dtype='float32')

imgs_holder = tf.placeholder(tf.float32, shape=[1, w, h, c])

logits = cnn.simple_net(imgs_holder)

saver = tf.train.Saver()
ckpt_dir = 'result/model_save/'

with tf.Session() as sess:
    ckpt = tf.train.get_checkpoint_state(ckpt_dir)
    saver.restore(sess, ckpt.model_checkpoint_path)
    classes_ = sess.run(logits,feed_dict={ imgs_holder: np.reshape(image_data , [1,w, h, c])})

num = np.argmax(classes_)
print('class is :',classes[int(num)],'  Probability is :',classes_[0][int(num)])

项目整体结构:
在这里插入图片描述
代码后期,将移植到github上,尽情期待。
坚持,感恩社会,努力,加油!

注:还可以用几种比较典型的卷积神经网络进行实现,比如lenet、alexnet、vggnet等等。

源码:
https://github.com/AugustMe/TensorFlow-Learn/tree/master/FlowersImageClassify

  • 4
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
好的,我明白了您的问题。这是一个图像分类问题,可以使用卷积神经网络来解决。下面是一个使用Keras框架搭建卷积神经网络模型,用于对五种不同的进行分类。 ```python import tensorflow as tf from tensorflow.keras import layers from tensorflow.keras.preprocessing.image import ImageDataGenerator # 设置数据集路径 train_dir = '/path/to/train' val_dir = '/path/to/val' # 设置输入数据大小和类别数 img_size = 224 num_classes = 5 # 数据增强 train_datagen = ImageDataGenerator( rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) val_datagen = ImageDataGenerator(rescale=1./255) train_generator = train_datagen.flow_from_directory( train_dir, target_size=(img_size, img_size), batch_size=32, class_mode='categorical') validation_generator = val_datagen.flow_from_directory( val_dir, target_size=(img_size, img_size), batch_size=32, class_mode='categorical') # 构建模型 model = tf.keras.Sequential([ layers.Conv2D(32, (3, 3), activation='relu', input_shape=(img_size, img_size, 3)), layers.MaxPooling2D((2, 2)), layers.Conv2D(64, (3, 3), activation='relu'), layers.MaxPooling2D((2, 2)), layers.Conv2D(128, (3, 3), activation='relu'), layers.MaxPooling2D((2, 2)), layers.Flatten(), layers.Dense(128, activation='relu'), layers.Dense(num_classes, activation='softmax') ]) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) # 训练模型 history = model.fit( train_generator, steps_per_epoch=100, epochs=20, validation_data=validation_generator, validation_steps=50) # 保存模型 model.save('flower_classification_model.h5') # 保存训练历史数据 import pickle with open('history.pickle', 'wb') as file_pi: pickle.dump(history.history, file_pi) ``` 在上面的代码中,我们使用了Keras中提供的ImageDataGenerator来进行数据增强。数据增强可以帮助我们扩充数据集,防止模型过拟合。同时,我们使用了三个卷积层和一个全连接层来构建模型。在训练完成后,我们将模型和训练历史数据保存到本地。 您可以将自己的数据集放在`train_dir`和`val_dir`所指定的路径中,并修改`img_size`和`num_classes`参数以适应您的数据集。另外,您需要修改`steps_per_epoch`和`validation_steps`参数来保证每个epoch中的训练和验证数据集的完整遍历。 在训练完成后,您可以使用以下代码来评估模型的准确度和损失: ```python # 评估模型 loss, accuracy = model.evaluate(validation_generator) print('Test accuracy:', accuracy) print('Test loss:', loss) ``` 您可以将训练好的模型用于新的图像分类任务中: ```python # 加载模型 model = tf.keras.models.load_model('flower_classification_model.h5') # 预测新的图像 import numpy as np from tensorflow.keras.preprocessing import image img_path = '/path/to/image' img = image.load_img(img_path, target_size=(img_size, img_size)) img_array = image.img_to_array(img) img_array = np.expand_dims(img_array, axis=0) predictions = model.predict(img_array) print(predictions) ``` 预测结果将是一个长度为5的数组,每个元素对应一种的概率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器不学习我学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值