序:本文作者是我们公司的AI工程师,本文在Gitchat原创首发,之后我们将会更多地跟大家探讨人工智能的话题。
不知不觉,人工智能已经悄然的走进我们的生活。在我们的潜意识里,还是将人工智能和智能人形机器人联系在一起,这是我们对人工智能的固有偏见。在2016年的云栖大会上,马云的演讲飞速的被翻译成文字,显示在现场的大屏幕上;自动驾驶是汽车产业与人工智能、物联网、高性能计算等新一代信息技术深度融合的产物,是当前全球汽车与交通出行领域智能化和网联化发展的主要方向,已成为各国争抢的战略制高点;手机中的语音助手Siri,总能和我们愉快的聊天;iPhone手机上的照片-相簿-人物中自动对照片中的人脸进行识别和归类,将包含一个人脸的照片放在同一个相簿里面;今日头条中推荐的新闻总是你感兴趣的东西,不同人打开淘宝App出来的界面总不一样。人工智能已经应用在我们生活的很多领域了。
图1 iPhone手机上照片人物相簿
到底什么是人工智能(AI),创新工场的李开复对AI在《人工智能》中列举了AI的五个常见定义:1)AI就是让人觉得不可思议的计算机程序;2)AI就是与人类思考方式相似的计算机程序;3) AI就是与人类行为相似的计算机程序;4)AI就是会学习的计算机程序;5)AI就是根据对环境的感知,做出合理的行动,并获得很大收益的计算机程序。从其五点定义中,我们可以很轻易的得到这个结论:AI就是计算机程序。当然并不仅仅是这样,详细点的概括为,AI是一种为了解决某些问题而人工设计出的计算机程序,这个程序的算法是模仿人类思考问题的方式,并且具有学习能力。
2016年,AlphaGo与李世石的围棋大战无疑成为人工智能的一道里程碑,也是人工智能的再一次复兴。反观AlphaGo低层算法原理,如下图2所示,需要收集大量棋手的棋谱,通说深度神经网络来训练模型。人工智能的这一次复兴的最大特点是,AI在语音识别、机器视觉、数据挖掘等多个领域走进了业界多个真实的应用场景,与商业模式紧密结合,开始在各个行业发挥出真正的价值。可以说新时期的人工智能模式为:深度学习+大数据。
图2 AlphaGo算法模式
现在我们走进深度学习,是机器学习的一个分支。深度学习算法可以从数据中学习更加复杂的特征表达,是最后一步的特征学习变得更加简单有效。就图像识别而言,深度学习可以一层一层地将简单的像素特征逐步转化成更加复杂的特征,从而使不同类别的图像更加可分。和传统机器学习相比,深度学习的特点主要体现在“深度”二字中,主要体现在网络结构的深度和提取的特征深度。本文主要针对的是深度学习在机器视觉上的应用,那么我们就绕不开一个重要的网络结构——卷积神经网路。
在早期的图像识别中,主要是从图像低层特征入手,对图像特征进行归纳分析,当然,组织特征也是图像识别技术最大的难点。卷积神经网络,英文全称为Convolutional Neural Network,简称CNN,在最开始就是专门用来解决图像中的物体识别等问题,现在,CNN的应用已经不仅仅局限于图像识别和视频处理,也被应用于时间序列信号的处理,比如识别音频信号、文本数据。
CNN起源于神经科学家对喵星人的大脑的研究,他们将电极插到猫的脑子里,去观察视觉皮层的活动,他们的经过研究推断出,生物视觉是从物体小的部分入手,经过层层的抽象,最后拼起来送入处理中心,减少物体判断物体的可疑性。显然,这个推断和我们普通的BP神经网络原理背道而驰,BP神经网络认为,大脑的每个神经元都要感知物体的全部像素点,即全像素全连接,并且知识简单的映射,并没有对物体进行抽象处理。然而CNN最先证明了BP神经网络理论的不合理性。
图3 LeNet网络结构
经典的CNN的网络结构如图3所示,卷积神经网络主要结构有:卷积层、池化层和全连接层。在LeNet的网络结构中,对于一个32×32的图像,首先用6个卷积核对图像进行卷积得到6×28×28的一对数据,然后对数据的每一维做一个池化,得到6×14×14的数据结构,后面再用有16个卷积核的卷积层对数据进行卷积得到16×10×10的数据结构,再用一个池化层对将数据简化成16×5×5,后面接一个全连接的神经网络。
图4所示为我们常用的卷积神经网络实例,变化比较多的可能是卷积层和池化层的层数,卷积层和池化层的之中可能会连接数次,还可以在所用卷积核的Size上面做文章,也能达到不同的效果。
图4 CNN运用实例
以Mnist数字集为例来构建自己的CNN网络,下文中分别用Keras和TensorFlow对CNN网络进行了实现,实现代码如下所示。
1)Keras实现代码:
import numpy
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')
seed = 7
numpy.random.seed(seed)
加载数据:
(X_train,y_train),(X_test,y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0],1,28,28).astype('float32')
X_test = X_test.reshape(X_test.shape[0],1,28,28).astype('float32')
X_train = X_train/255
X_test = X_test/255
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]
def baseline_model():
构建模型:
model = Sequential()
model.add(Convolution2D(30,5,5,border_mode='valid',input_shape=(1,28,28),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Convolution2D(15,3,3,activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128,activation='relu'))
model.add(Dense(50,activation='relu'))
model.add(Dense(num_classes,activation='softmax')) model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
return model
model = baseline_model()
model.fit(X_train,y_train,validation_data=(X_test,y_test),nb_epoch=10,batch_size=200,verbose=2)
scores = model.evaluate(X_test,y_test,verbose=0)
print("Baseline Error: %.2f%%" % (100-scores[1]*100))
2)TensorFlow实现
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
sess = tf.InteractiveSession()
一、函数声明部分
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],strides=[1, 2, 2, 1], padding='SAME')
二、定义输入输出结构
xs = tf.placeholder(tf.float32, [None, 28*28])
ys = tf.placeholder(tf.float32, [None, 10])
keep_prob = tf.placeholder(tf.float32)
x_image = tf.reshape(xs, [-1, 28, 28, 1])
三、搭建网络,定义算法公式,也就是forward时的计算
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
w_conv2 = weight_variable([5,5,32,64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1,w_conv2)+b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
W_fc1 = weight_variable([7*7*64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7*7*64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(f_fc1,keep_prob)