用keras作CNN卷积网络书本分类(书本、非书本)

本文介绍如何使用keras作图片分类(2分类与多分类,其实就一个参数的区别。。。呵呵)

先来看看解决的问题:从一堆图片中分出是不是书本,也就是最终给图片标签上:“书本“、“非书本”,简单吧。

先来看看网络模型,用到了卷积和全连接层,最后套上SOFTMAX算出各自概率,输出ONE-HOT码,主要部件就是这些,下面的nb_classes就是用来控制分类数的,本文是2分类:

from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.optimizers import SGD  

def Net_model(nb_classes, lr=0.001,decay=1e-6,momentum=0.9):
    model = Sequential()
    model.add(Convolution2D(filters=10, kernel_size=(5,5),
                            padding=‘valid‘,
                            input_shape=(200, 200, 3)))
    model.add(Activation(‘tanh‘))
    model.add(MaxPooling2D(pool_size=(2, 2)))  

    model.add(Convolution2D(filters=20, kernel_size=(10,10)))
    model.add(Activation(‘tanh‘))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))  

    model.add(Flatten())
    model.add(Dense(1000))
    model.add(Activation(‘tanh‘))
    model.add(Dropout(0.5))
    model.add(Dense(nb_classes))
    model.add(Activation(‘softmax‘))  

    sgd = SGD(lr=lr, decay=decay, momentum=momentum, nesterov=True)
    model.compile(loss=‘categorical_crossentropy‘, optimizer=sgd)  

    return model

上面的input_shape=(200, 200, 3)代表图片像素大小为宽高为200,200,并且包含RGB 3通道的图片,不是灰度图片(只要1个通道)

也就是说送入此网络的图片宽高必须200*200*3;如果不是这个shape就需要resize到这个shape

下面来看看训练程序,首先肯定是要收集些照片,书本、非书本的照片,我是分别放在了0文件夹和1文件夹下了,再带个验证用途的文件夹validate:

  

训练程序涉及到几个地方:照片文件的读取、模型加载训练与保存、可视化训练过程中的损失函数value

照片文件的读取

import cv2
import os
import numpy as np
import keras

def loadImages():
    imageList=[]
    labelList=[]

    rootdir="d:\\books\\0"
    list =os.listdir(rootdir)
    for item in list:
        path=os.path.join(rootdir,item)
        if(os.path.isfile(path)):
            f=cv2.imread(path)
            f=cv2.resize(f, (200, 200))#resize到网络input的shape
            imageList.append(f)
            labelList.append(0)#类别0

    rootdir="d:\\books\\1"
    list =os.listdir(rootdir)
    for item in list:
        path=os.path.join(rootdir,item)
        if(os.path.isfile(path)):
            f=cv2.imread(path)
            f=cv2.resize(f, (200, 200))#resize到网络input的shape
            imageList.append(f)
            labelList.append(1)#类别1

    return np.asarray(imageList), keras.utils.to_categorical(labelList, 2)

关于(200,200)这个shape怎么得来的,只是几月前开始玩opencv时随便写了个数值,后来想利用那些图片,就适应到这个shape了

keras.utils.to_categorical函数类似numpy.onehot、tf.one_hot这些,只是one hot的keras封装

模型加载训练与保存

nb_classes = 2
nb_epoch = 30
nb_step = 6
batch_size = 3

x,y=loadImages()

from keras.preprocessing.image import ImageDataGenerator
dataGenerator=ImageDataGenerator()
dataGenerator.fit(x)
data_generator=dataGenerator.flow(x, y, batch_size, True)#generator函数,用来生成批处理数据(从loadImages中)

model=NetModule.Net_model(nb_classes=nb_classes, lr=0.0001) #加载网络模型

history=model.fit_generator(data_generator, epochs=nb_epoch, steps_per_epoch=nb_step, shuffle=True)#训练网络,并且返回每次epoch的损失value

model.save_weights(‘D:\\Documents\\Visual Studio 2017\\Projects\\ConsoleApp9\\PythonApplication1\\书本识别\\trained_model_weights.h5‘)#保存权重
print("DONE, model saved in path-->D:\\Documents\\Visual Studio 2017\\Projects\\ConsoleApp9\\PythonApplication1\\书本识别\\trained_model_weights.h5")

ImageDataGenerator构造函数有很多参数,主要用来提升数据质量,比如要不要标准化数字

lr=0.001这个参数要看经验,大了会导致不收敛,训练的时候经常由于这个参数的问题导致重复训练,这在没有GPU的情况下很是痛苦。。痛苦。。。痛苦。。。

model.save_weights是保存权重,但是不保存网络模型 ,对应的是model.load_weights方法

model.save是保存网络+权重,只是。。。。此例中用save_weights保存的h5文件是125M,但用save方法保存后,h5文件就增大为280M了。。。

上面2个save方法都能finetune,只是灵活度不一样。

可视化训练过程中的损失函数value

import matplotlib.pyplot as plt

plt.plot(history.history[‘loss‘])
plt.show()

  

貌似没啥好补充的。。。

AND。。。。看看预测部分吧,这部分加载图片、加载模型,似乎都和训练部分雷同:

def loadImages():
    imageList=[]

    rootdir="d:\\books\\validate"
    list =os.listdir(rootdir)
    for item in list:
        path=os.path.join(rootdir,item)
        if(os.path.isfile(path)):
            f=cv2.imread(path)
            f=cv2.resize(f, (200, 200))
            imageList.append(f)

    return np.asarray(imageList)

x=loadImages()

x=np.asarray(x)

model=NetModule.Net_model(nb_classes=2, lr=0.0001)
model.load_weights(‘D:\\Documents\\Visual Studio 2017\\Projects\\ConsoleApp9\\PythonApplication1\\书本识别\\trained_model_weights.h5‘)

print(model.predict(x))
print(model.predict_classes(x))
y=convert2label(model.predict_classes(x))
print(y)

predict的返回其实是softmax层返回的概率数值,是<=1的float

predict_classes返回的是经过one-hot处理后的数值,此时只有0、1两种数值(最大的value会被返回称为1,其他都为0)  

convert2label:

def convert2label(vector):
    string_array=[]
    for v in vector:
        if v==1:
            string_array.append(‘BOOK‘)
        else:
            string_array.append(‘NOT BOOK‘)
    return string_array

这个函数是用来把0、1转换成文本的,小插曲:

本来这里是中文的“书本”、“非书本”,后来和女儿一起调试时发现都显示成了问号,应该是中文字符问题,就改成了英文显示,和女儿一起写代码是种乐趣啊!

本来只是显示文本,感觉太无聊了,因此加上了opencv显示图片+分类文本的代码段:

for i in range(len(x)):
    cv2.putText(x[i], y[i], (50,50), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)
    cv2.imshow(‘image‘+str(i), x[i])

cv2.waitKey(-1)

  

OK, 2018年继续学习,继续科学信仰。

原文地址:https://www.cnblogs.com/aarond/p/CNN.html

时间: 2024-10-08 02:14:10

用keras作CNN卷积网络书本分类(书本、非书本)的相关文章

1. CNN卷积网络初识

1. 前言 卷积神经网络是一种特殊的深层的神经网络模型,它的特殊性体现在两个方面, 它的神经元间的连接是非全连接的, 同一层中某些神经元之间的连接的权重是共享的(即相同的). 它的非全连接和权值共享的网络结构使之更类似于生物 神经网络,降低了网络模型的复杂度(对于很难学习的深层结构来说,这是非常重要的),减少了权值的数量. 2. CNN卷积网络结构 我们先重整体的角度观察一下CNN卷积网络的结构: 上图的结构从左到右是,输入层.卷积层(Convolution Layer).池化层(Pooling

利用keras搭建CNN进行mnist数据集分类

当接触深度学习算法的时候,大家都很想自己亲自实践一下这个算法,但是一想到那些复杂的程序,又感觉心里面很累啊,又要学诸如tensorflow.theano这些框架.那么,有没有什么好东西能够帮助我们快速搭建这个算法呢?当然是有咯!,现如今真不缺少造轮子的大神,so,我强烈向大家推荐keras,Keras是一个高层神经网络API,Keras由纯Python编写而成并基Tensorflow或Theano.Keras为支持快速实验而生,能够把你的idea迅速转换为结果. 具体keras的安装与使用,请参

深度卷积网络CNN与图像语义分割

转载请注明出处: http://xiahouzuoxin.github.io/notes/ 级别1:DL快速上手 级别2:从Caffe着手实践 级别3:读paper,网络Train起来 级别3:Demo跑起来 读一些源码玩玩 熟悉Caffe接口,写Demo这是硬功夫 分析各层Layer输出特征 级别4:何不自己搭个CNN玩玩 级别5:加速吧,GPU编程 关于语义分割的一些其它工作 说好的要笔耕不缀,这开始一边实习一边找工作,还摊上了自己的一点私事困扰,这几个月的东西都没来得及总结一下.这就来记录

机器学习-计算机视觉和卷积网络CNN

概述 对于计算机视觉的应用现在是非常广泛的,但是它背后的原理其实非常简单,就是将每一个像素的值pixel输入到一个DNN中,然后让这个神经网络去学习这个模型,最后去应用这个模型就可以了.听起来是不是很简单,其实如果大家深入研究的话,这里面还是有很多内容去学习的,例如:咱们的图片大小可能不一样,同一张图片不同的旋转角度可到的结果可能不一样,如何给咱们的本地图片来label(实际中并不是所有的数据都想mnist那样,谷歌都给咱们label好了,拿来用就行),等等这些问题咱们在实际中肯定都是要用到的.

CNN卷积神经网络_深度残差网络 ResNet——解决神经网络过深反而引起误差增加的根本问题

from:https://blog.csdn.net/diamonjoy_zone/article/details/70904212 环境:Win8.1 TensorFlow1.0.1 软件:Anaconda3 (集成Python3及开发环境) TensorFlow安装:pip install tensorflow (CPU版) pip install tensorflow-gpu (GPU版) TFLearn安装:pip install tflearn 参考: Deep Residual Le

Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN

http://m.blog.csdn.net/blog/wu010555688/24487301 本文整理了网上几位大牛的博客,详细地讲解了CNN的基础结构与核心思想,欢迎交流. [1]Deep learning简介 [2]Deep Learning训练过程 [3]Deep Learning模型之:CNN卷积神经网络推导和实现 [4]Deep Learning模型之:CNN的反向求导及练习 [5]Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN [6]Deep Learn

深度卷积网络

深度卷积网络 涉及问题: 1.每个图如何卷积: (1)一个图如何变成几个? (2)卷积核如何选择? 2.节点之间如何连接? 3.S2-C3如何进行分配? 4.16-120全连接如何连接? 5.最后output输出什么形式? ①各个层解释: 我们先要明确一点:每个层有多个Feature Map,每个Feature Map通过一种卷积滤波器提取输入的一种特征,然后每个Feature Map有多个神经元. C1层是一个卷积层(为什么是卷积?卷积运算一个重要的特点就是,通过卷积运算,可以使原信号特征增强

CNN眼中的世界:利用Keras解释CNN的滤波器

目录 原文信息 使用Keras探索卷积网络的滤波器 可视化所有的滤波器 Deep Dream(nightmare) 愚弄神经网络 革命尚未成功,同志仍需努力 原文信息 本文地址:http://blog.keras.io/how-convolutional-neural-networks-see-the-world.html 本文作者:Francois Chollet 本文的翻译版最先由我发布在Keras中文文档,为了方便各位网友,特将此文搬移到CSDN. 使用Keras探索卷积网络的滤波器 本文

用numpy实现CNN卷积神经网络

为了加深对卷积神经网络底层原理的理解,本文通过使用numpy来搭建一个基础的包含卷积层.池化层.全连接层和Softmax层的卷积神经网络,并选择relu作为我们的激活函数,选择多分类交叉熵损失函数,最后使用了mnist数据集进行了训练和测试. 关于卷积网络的详细原理和实现可参考下列文章: 刘建平Pinard:卷积网络前向反向传播算法 卷积层的反向传播 手把手带你 Numpy实现CNN 1.卷积层 卷积层的前向传播输出由卷积核和特征图作卷积运算得到,反向传播时需要计算kernel和bias的梯度以