jpeg解码的verilog代码_CNN卷积神经网络入门个人理解和实例代码(注释详细,一劳永逸)...

不铺垫啥了,最近看深度学习和神经网络有一点启发,想写个文章算是做个记录,直接开始吧。我看的是b站李宏毅老师的机器学习视频。

我比较懒,了解完原理,写完一遍代码之后,就想写一个一劳永逸的代码,想着以后有不同的应用场景需要,直接改几个参数然后调用就行了,所以这也是我特别喜欢写注释的原因。写注释是就为了一劳永逸。

当然,做图片分类,大概分为三个过程。

第一,收集你的数据,把它做成数据集(后面我是把数据集做出.npy格式),然后对数据预处理一下。具体就是把你的数据按类分好(丢到不同类名称的文件夹里),然后用代码把整体数据分成训练集、验证集、测试集和生成对应的训练集label、验证集_label、测试集_label。

第二、搭建卷积神经网络,把训练好的模型保存为.h5文件。搭建神经网络主要是要确定你处理数据的卷积层结构是什么,比如一张图片进去,要经过的卷积层的filter什么样,池化层什么样,打算设计几个,最后把得到的数据flatten拉直成一个向量,把这个向量丢到一个全连接层去跑(这整个第二步就叫卷积 神经网络,卷积就是数据去全连接层训练前的一种处理方式,没有卷积处理层只有全连接层的神经网络就叫DNN深度神经网络)。

第三、调用保存的模型对某一张图片预测它的类别,输出预测结果。

贴代码:

接下来以给花分类为例子,给出详细的代码。

注:花的数据集和.npy文件的创建代码是参考了这篇博文,后面附上博文的转载版权声明(版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本文链接: https:// blog.csdn.net/umbrellal alalala/article/details/86516928 )

第一、收集数据,放到数据文件夹里面去分好类,一个类一个文件夹(如图),然后做成.npy文件,生成的.npy为6维数组,分别是训练集,训练集标签,验证集,验证集标签,测试集,测试集标签。其中训练集的数据是随机打乱了的,标签对应也是;而训练集、验证集和测试集的数据都是来自于数据文件夹,按比例确定的,比如随机拿出10%做验证集,10%测试集,剩下的当作数据集。注:文件名不能有中文

jpeg解码的verilog代码_CNN卷积神经网络入门个人理解和实例代码(注释详细,一劳永逸)..._第1张图片
文件夹名就是类别名,里面是同一类的图片
# -*- coding: utf-8 -*-

第二、搭建卷积神经网络,保存模型为.h5文件。

代码如下:

# -*- coding:utf-8 -*-

import numpy as np
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D, Flatten, Conv2D
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD, Adam
from keras.utils import np_utils
from keras.datasets import mnist

# categorical_crossentropy


def load_mnist_data(number):
    # the data, shuffled and  split between train and test sets
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    x_train = x_train[0:number]
    y_train = y_train[0:number]
    x_train = x_train.reshape(number, 784)
    x_test  = x_test.reshape(10000, 784)
    x_train = x_train.astype('float32')
    x_test = x_test.astype('float32')
    # convert class vectors to binary class matrices
    y_train = np_utils.to_categorical(y_train, 10)
    y_test = np_utils.to_categorical(y_test, 10)
    print(x_test.shape)
    x_train = x_train / 255
    x_test = x_test / 255

    return (x_train, y_train), (x_test, y_test)


if __name__ == '__main__':
    (x_train, y_train), (x_test, y_test) = load_mnist_data(10000)    # 测试集里面只有10000张照片
    print(x_test.shape)

    # do CNN
    x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
    x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)

    model2 = Sequential()
    model2.add(Conv2D(25, (3, 3), input_shape=(
         28, 28, 1), data_format='channels_last'))
    model2.add(MaxPooling2D((2, 2)))
    model2.add(Conv2D(50, (3, 3)))
    model2.add(MaxPooling2D((2, 2)))
    model2.add(Flatten())
    model2.add(Dense(units=100, activation='relu'))
    # 最后要分成十类,所以要用10个单元
    model2.add(Dense(units=10, activation='softmax'))
    model2.summary()
    
    model2.compile(loss='categorical_crossentropy',
                    optimizer='adam', metrics=['accuracy'])
    
    model2.fit(x_train, y_train, batch_size=100, epochs=20)
    # 打印在训练集上的训练结果
    result_train = model2.evaluate(x_train, y_train)
    print('nTrain CNN Acc:n', result_train[1])
    # 打印在测试集上的测试结果
    result_test = model2.evaluate(x_test, y_test)
    print('nTest CNN Acc:n', result_test[1])
    # 保存模型为.h5,方便下次预测
    model2.save('E:projectsmanchine_learningcnnhandwirte.h5')

jpeg解码的verilog代码_CNN卷积神经网络入门个人理解和实例代码(注释详细,一劳永逸)..._第2张图片
训练的时候超了一点内存,训练完大概花了25分钟

jpeg解码的verilog代码_CNN卷积神经网络入门个人理解和实例代码(注释详细,一劳永逸)..._第3张图片
训练精度和测试进度都差不多是90%,还是比较低的,可能是模型不够复杂,也可能是数据集不够大,待会拿几张图片测试一下

第三、调用保存的模型对某一张图片预测它的类别,输出预测结果。

# -*- coding:utf-8 -*-
import  PIL
import keras
import matplotlib
import os
import numpy as np
from PIL import Image
import cv2

# 读取模型
model = keras.models.load_model('E:projectsmanchine_learningcnnflowerrecong.h5')
# 要预测的图片保存在下面这个文件夹内
sub_dirs = 'C:UserswildpigDesktoptest'
# 定义一个列表来存储类别名称
classcatalogue = ['雏菊', '蒲公英', '玫瑰', '向日葵', '郁金香']
# 下面的2表示返回所有文件名,0表示代表目录的路径,1表示子目录名字,没有就是[]
sub_dir = [x[2] for x in os.walk(sub_dirs)]
# 遍历每一个文件名,代入模型预测
for sub in sub_dir[0]:
    image = cv2.imread(sub_dirs + '' + sub)
    img = cv2.resize(image, (299, 299)) / 255    # 调整像素保存和训练模型中的像素一致
    # 需要用reshape定义出例子的个数,图片的 通道数,图片的长与宽。具体的参加keras文档
    img = (img.reshape(1, 299, 299, 3)).astype('float32')
    predict = np.argmax(model.predict(img), axis=-1)
    # predict = model.predict_classes(img)
    # 输出预测结果,格式为   ‘图片名称’+‘识别为:’+‘类别’
    print(sub, '识别为:', classcatalogue[int(predict)])
    # 如果预测的图片不多,还可以打开照片看下
    # cv2.imshow("Image1", img)
    # cv2.waitKey(0)

jpeg解码的verilog代码_CNN卷积神经网络入门个人理解和实例代码(注释详细,一劳永逸)..._第4张图片
测试了几张图片,识别率较一般,好几个没识别对,这个应该属于variance比较大,模型再复杂点就好了(比如多弄几个全连接层,多来几套卷积层(包括卷积池化)),刚才训练的模型准确度是89%这样子。

下面瞎扯点皮:

深度学习,从属于机器学习里的一类操作。本质上是让计算机帮助我们去处理复杂的回归问题,有点像大学数学实验课程里的拟合一个函数的练习。而神经网络则是处理回归问题的一种方法,往往是在数据量特别大的时候用神经网络去算回归的函数的参数。如果数据量不多,参数自然也不会太多,这时候可以直接用回归方法去跑,比如一些基于梯度的下降算法,手写代码还更清晰方便调试。

CNN/DNN,就是卷积神经网络和深度神经网络,是针对回归问题中数据量特别大的分类问题的处理模式。而回归问题,就是根据一些已知的数据,去预测一件事情会有怎样的结果,这个结果往往会受到一些相关因素的影响,这些因素可以根据问题相应的理论来确定,也可以人为经验来设定。就比如空气中PM2.5的值,我们可以说它和前8个小时的空气成分的含量有关,我也可以单独认为它和前一个礼拜的PM2.5含量有关。类似的,我们数据建立模型,用机器学习去把目标函数的参数迭代出来之后,我们不进可以对目标进行预测,也可以根据预测结果去对目标进行分类。

比如说:我有一些点(xdata, ydata),我可以去找一个函数去拟合这些数据,当然,我们假设出这些点的关系可能是某一个函数关系时,会带有一些参数(如y=kx+b,k,b就是未知参数),那么最好的函数就要满足所有的

的值要最小,也就是找k,b,使得
最小。那么这时,用下降算法就可以求出使得y这条曲线拟合这些数据的效果最好的k和b。这样,就可以拿着这个函数去预测其它xdata点处的ydata是什么(这就是回归),也可以给你一个点(x,y)去判断这个点在什么地方,是在这条线的哪一侧?(这就是分类,就是DNN和CNN做的事情)

本文的卷积神经网络就是处理分类问题的。

先说做卷积神经网络的目的是什么?/问题是什么?

问题/目的就是:给你一些大量的数据,比如很多手写的数字图片,比如很多种花的图片,要你训练一个模型/函数,能够让我下次丢一张图片(手写数字图片/花的图片)进去,函数可以把图片的类比输出出来(0-9/花的名字)。

几点思考:

1、深度学习做的就是找函数的事情,只不过这个函数的输出是类别,不像一般的机器学习输出的是数值。不过都没关系啦,类别都是自己定的,比如识别花的种类里面,我可以让函数值是1的时候表示玫瑰花,然后输出玫瑰。

2、找函数,本质是回归,就是自己假设可能是一个什么函数,比如线性函数还是非线性函数,是一次函数还是二次函数,等等。然后假设出来了,就是跑优化算法去求解函数里的参数了,找到最好的那个参数,作为你的最终模型。所以我们很容易明白,不同的人、不同的初试数据、甚至人品,都会导致每个人找的函数都是不一样的。就算是同一个模型,放到不同电脑上去跑,得到的具体参数都有可能不同,不过函数/模型的框架是不变的。就比如y=kx+b,每个人的k,b可能都不太一样,但是形式是一样的,用同一个数据集,同样的条件下,训练出来的模型,参数也不会相差太大。

3、神经网络就是应对数据集很大的时候的一种回归方法。假如说就几个子数据,比如100个数据点,让你去拟合一个函数,那不就直接假设函数表达式(比如y=kx+b),然后求loss function的微分,用梯度下降就可以求得最好的k,b了。但是当数据集很大时,比如说数据集是很多图片,去预测图片的种类。这时,我们假设每一张图片都是

像素的,那相当于每一个xdata都是一个784维的向量,虽然你也可以硬核的去用回归办法去求解,比方说我假设图片和类别之间的函数关系是:
。完事儿我把所有的图片导入,写出loss function,计算微分,梯度下降,成了。可是这样有局限性,也很麻烦,是很容易出问题的。

哪些问题:

1、图片的数据量太大了(对于优化来说,并不是图片说占的存储空间大,现在固态多便宜啊),导致input很多,使得模型的参数要很多(起码input有多少维就该先有多少参数吧),计算量很大,耗时长。

2、光看input维度是不够的,因为有的图片分辨率不一样,维度也会变。所以先定下模型,相当于定死了图片的分辨率,不具有一般性,无法利用到图像的结构特征,模型根本没有学习到不同种类的花的特征。

这个时候神经网络就出现了。

jpeg解码的verilog代码_CNN卷积神经网络入门个人理解和实例代码(注释详细,一劳永逸)..._第5张图片

神经网络,用多个neuron去拟合数据的每一个维度,它就好比是

,而
,
就是输入,
就是输出。本质上是很多个线性模型的复合,而一般的连续函数
(因为我们要用梯度嘛,所以函数肯定是假设连续的),都可以分成正部
和负部
,而任何一个非负函数都可以用简单函数逼近,自然也可以用线性函数逼近。或者换个说法,连续函数可以展开成泰勒函数,就是一个多项式函数,刚刚的多个线性函数复合的结果就是多项式函数,所以神经网络找函数的办法是可行的。

而且神经网络也有许多优势,暂时写两个比较喜欢的:一个是对数据量比较大是,用多层的hidden layer会比直接手写代码算拟合函数,在求解最优参数的速度上会更快。另一个是神经网络这种传递模型,在更新计算时,每一个neuron的完整输入输出可以看作一个矩阵乘法

,这样的话可以用gpu加速并行计算,数据量大的时候速度比手撸代码快多了。还有很多优点就不写了。

你可能感兴趣的:(matlab卷积神经网络代码)