首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

未来的人工智能将有神经元结构?谷歌 Tensorflow 系统已经实现

神经网络是Tensorflow最擅长的机器学习领域。TensorFlow拥有一套符号引擎,它使得训练复杂模型变得更简单和方便。通过这套符号引擎,我们能够实现许多的模型结构和算法。

本文中,我们将会覆盖以下内容:

神经网络的基本概念;

神经网络用于回归非线性合成函数;

使用非线性回归预测汽车燃料效率;

学习葡萄酒分类——一种多类分类。

5.1.1 人工神经元

人工神经元就是使用一个数学函数来对生物的神经元建模。

简单来说,一个人工神经元就是接受一个或者多个输入(训练数据),对它们加和,并产生一个输出。一般来说,这里面的加和指的是加权求和(每个输入乘上权重,并加上一个偏差),然后将加和的输入传递给一个非线性函数(一般称作激活函数或者转移函数)。

1.最简单的人工神经元——感知器

感知器是实现人工神经元最简单的方法,它的历史可以追溯到20世纪50年代,在20世纪60年代的时候,首次被实现。

简单来说,感知器就是一个二元分类函数,它将输入映射到一个二元输出,如图5-1所示。

图5-1 单层感知器

2.感知器算法

简化版的感知器算法如下:

以一个随机分布初始化权值和偏差(通常比较小);

选择一个输入向量,并将其放入神经网络中;

将输入与权重相乘,并加上偏差,计算网络的输出y';

感知器的函数如下:

如果y′≠y,将权重wi加上Δw=yxi;

返回第步。

5.1.2 神经网络层

我们可以对单层的感知器进行泛华,将它们堆积起来,并互相连接,如图5-2所示。但这就带来一个问题,这样的线性组合出来的模型还只是一个线性分类器,对于复杂的非线性分类,这种方式并不能正确拟合,这个问题需要激活函数来解决。

1.神经网络激活函数

单独的单变量线性分类器并不能带来神经网络的强悍性能。就算那些不是很复杂的机器学习问题都会涉及多变量和非线性,所以我们常常要用其他的转移函数来替代感知器中原本的转移函数。

图5-2 连接单层感知器

有很多非线性函数可以用来做激活函数,从而表征不同的非线性模型。在输入同样的变量的时候,不同的激活函数有不同的响应。常用的激活函数如下:

Logistic:典型的激活函数,在计算分类的概率时非常有用。

Tanh:跟Sigmoid函数很像,但是范围是[−1,1],而不是[0,1]。

Relu:修正线性函数,该函数主要是为了对抗梯度消失。也就是当梯度反向传播到第一层的时候,梯度容易趋近于0或者一个极小值。

{-:-}f(x)=max(0, x)

在我们计算总的误差的时候,因为是一整个函数作用于输入数据,所以我们要调整这个方程中的所有变量,来最小化方程。

怎样最小化误差呢?正如我们在优化部分所学,我们通过损失函数的梯度来最小化误差。

如果我们的网络拥有多层权重和转移函数,我们最终需要通过链式法则来求导所有参数的梯度。

2.梯度和反向传播算法

在感知器的学习阶段,我们按照每个权重对误差的“责任”,按比例调整权重。

在更复杂的网络中,误差的责任被分散在整个结构的所有操作之中。

3.最小化损失函数:梯度下降

我们由图5-3理解一下损失函数。

4.神经网络的选择-分类vs回归

神经网络既可以被用于回归问题,也可以被用于分类问题。不同的地方在于结构的最后一层。如果需要的结果是一个数值,那么就不要连接标准函数,如 sigmoid。如果是这样的话,我们得到的就是一个连续值。

图5-3 梯度下降

5.1.3 有用的库和方法

本章中我们会用到TensorFlow中一些新的函数,下面是我们需要的最重要的函数:

1.TensorFlow激活函数

最常用的激活函数如下:

tf.sigmoid(x):标准的sigmoid函数;

tf.tanh(x):双曲正切函数;

TensorFlow中其他的函数:

tf.softsign(x):返回x/(abs(x)+1);

2.TensorFlow中损失优化方法

tf.train.GradientDescentOptimizer(learningrate, uselocking, name):原始梯度下降方法,唯一参数就是学习率。

tf.train.AdagradOptimizer:自适应调整学习率,累加历史梯度的平方,作为分母,防止有些方向的梯度值过大,提高优化效率,善于处理稀疏梯度。

tf.train.AdadeltaOptimizer:扩展AdaGrad优化方法,只累加最近的梯度值,而不对整个历史上的梯度值进行累加。

tf.train.AdamOptimizertf.train.AdamOptimizer. (learningrate, beta1, beta2, epsilon, use locking, name):梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam是自适应矩估计(Adaptive Moment Estimation)的首字母缩写。

3.Sklearn预处理函数

我们看一些下面的Sklearn数据预处理函数:

preprocessing.StandardScaler():数据正规化(Normalization)是机器学习估计的一个常见要求,为了模型能更好地收敛,我们通常会将数据集预处理到一个零均值单位方差的高斯状分布。通常,我们会将数据的各个维度都减去它的均值,然后乘上一个非零的数。这个非零的数就是数据集的标准差。对于该任务,我们直接使用StandardScaler,它已经实现了我们上面提到的操作。它也保留了变换操作,让我们可以直接用在测试集上。

StandardScaler .fit_transform():将数据调整到所需要的形式。StandardScaler对象会存储数据变化的变量,这样我们可以把数据解正规化到原先的格式。

crossvalidation.traintest_split:该方法能够将数据集分割成训练集和测试集。我们只需要提供两者的比例,该方法能够自动帮我们处理。

5.2 例1——非线性模拟数据回归

人工神经网络的应用包含了很多的分类任务,但是事实上,很多这些分类任务都是用回归来实现的。

分类和回归的网络结构差的并不多,都可以使用多变量的输入,以及线性或者非线性的激活函数。

在一些例子中,唯一要变的就是在输出层,连接上Sigmoid状的函数,该函数能够表征结果为各个类别的可能性。

在第一个例子中,我们使用一个简单的带噪声的二次方程生成样本。模型我们使用带一个隐含层的神经网络,然后检测预测值跟真实值的距离远近。

5.2.1 数据集描述和加载

本例中,我们使用生成的数据集,这跟第3章线性回归类似。

我们这次选择的方程是一个二次方程,并加上随机噪声,这有助于帮助我们测试回归的泛化能力。

核心代码如下:

import numpy as np

trainsamples = 200

testsamples = 60

dsX = np.linspace(-1, 1, trainsamples + testsamples).transpose()

5.2.2 数据集预处理

本例中的数据集不需要预处理,因为它是我们人工生成的,具有更好的性能,比如能够保证数据范围是(−1,1)。

5.2.3 模型结构——损失函数描述

本例中的损失函数使用均方误差,由以下代码实现:

cost = tf.pow(py_x-Y, 2)/(2)

5.2.4 损失函数优化器

本例中,我们使用梯度下降作为损失函数优化器,可以用以下代码实现:

train_op = tf.train.AdamOptimizer(0.5).minimize(cost)

5.2.5 准确度和收敛测试

predict_op = tf.argmax(py_x, 1)

cost1 += sess.run(cost, feed_dict=) / testsamples

5.2.6 完整源代码

完整源代码如下:

import tensorflow as tf

import numpy as np

from sklearn.utils import shuffle

%matplotlib inline

import matplotlib.pyplot as plt

trainsamples = 200

testsamples = 60

#Here we will represent the model, a simple imput, a hidden layer of

sigmoid activation

def model(X, hidden_weights1, hidden_bias1, ow):

return tf.matmul(hidden_layer, ow)

dsX = np.linspace(-1, 1, trainsamples + testsamples).transpose()

plt.figure() # Create a new figure

plt.title('Original data')

plt.scatter(dsX,dsY) #Plot a scatter draw of the datapoints

X = tf.placeholder("float")

Y = tf.placeholder("float")

# Create first hidden layer

hw1 = tf.Variable(tf.random_normal([1, 10], stddev=0.1))

# Create output connection

ow = tf.Variable(tf.random_normal([10, 1], stddev=0.0))

# Create bias

b = tf.Variable(tf.random_normal([10], stddev=0.1))

model_y = model(X, hw1, b, ow)

# Cost function

cost = tf.pow(model_y-Y, 2)/(2)

# construct an optimizer

train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)

# Launch the graph in a session

with tf.Session() as sess:

tf.initialize_all_variables().run() #Initialize all variables

for i in range(1,100):

dsX, dsY = shuffle (dsX.transpose(), dsY) #We randomize the samples

to mplement a better training

trainX, trainY =dsX[0:trainsamples], dsY[0:trainsamples]

for x1,y1 in zip (trainX, trainY):

sess.run(train_op, feed_dict=)

testX, testY = dsX[trainsamples:trainsamples + testsamples],

dsY[0:trainsamples:trainsamples+testsamples]

cost1=0.

for x1,y1 in zip (testX, testY):

cost1 += sess.run(cost, feed_dict=) /

testsamples

if (i%10 == 0):

print "Average cost for epoch " + str (i) + ":" + str(cost1)

5.2.7 结果描述

生成的人工数据的散点图如图5-4所示。

图5-4 人工数据散点图

由以下每次迭代的结果,我们知道该实现结果非常好,甚至在第一次迭代的时候就取得了不错的结果。

Average cost for epoch 9:[[ 0.0007379]]

5.3 例2——通过非线性回归,对汽车燃料效率建模

本例中,我们会进入一个新的领域:解决非线性问题。该领域是神经网络附加值最大的领域。开始该旅程之前,我们会对几个汽车型号的燃料效率建模。该问题的输入是多个变量,只有非线性模型才能取得比较好的结果。

5.3.1 数据集描述和加载

对该问题,我们会分析一个著名的、标准的、数据组织得很好的数据集。我们有一个多变量的输入(有连续的,也有离散的),预测每加仑英里数(mpg)。

这是一个玩具级例子,但是这个例子会铺开通往更复杂问题的道路。而且该例子还有个好处,就是被大量研究过。

数据集由如下的列组成。

mpg:每加仑英里数,连续。

cylinders:气缸,多值离散。

displacement:排量,连续。

horsepower:马力,连续。

weight:车重,连续。

acceleration:加速度,连续。

model year:年份,多值离散。

origin:产地,多值离散。

car name:车名,字符串(不会被使用)。

我们不会对该数据做详细的分析,我们只是想看一下每一个连续的变量都跟目标变量的增减相关,如图5-5所示。

图5-5 不同的变量和燃烧效率的关系散点图

5.3.2 数据预处理

本例中,我们会使用一个前面描述的sklearn中的StandardScaler对象:

scaler = preprocessing.StandardScaler()

Xtrain = scaler.fittransform(X_train)

5.3.3 模型架构

我们需要建立的是一个多变量输入,单变量输出的前向神经网络,如图5-6所示。

图5-6 模型架构

5.3.4 准确度测试

我们用以下代码实现准确度测试:

score =

metrics.mean_squared_error(regressor.predict(scaler.transform(X_test)),

y_test)

print(" Total Mean Squared Error: " + str(score))

5.3.5 结果描述

Step #99, avg. train loss: 182.33624

Step #199, avg. train loss: 25.09151

Step #300, epoch #1, avg. train loss: 11.92343

Step #400, epoch #1, avg. train loss: 11.20414

Step #500, epoch #1, avg. train loss: 5.14056

5.3.6 完整源代码

完整源代码如下:

%matplotlib inline

import matplotlib.pyplot as plt

import pandas as pd

from sklearn import datasets, cross_validation, metrics

from sklearn import preprocessing

from tensorflow.contrib import skflow

# Read the original dataset

df = pd.read_csv("data/mpg.csv", header=0)

# Convert the displacement column as float

df['displacement']=df['displacement'].astype(float)

# We get data columns from the dataset

# First and last (mpg and car names) are ignored for X

X = df[df.columns[1:8]]

y = df['mpg']

plt.figure() # Create a new figure

for i in range (1,8):

number = 420 + i

ax1.locator_params(nbins=3)

ax1 = plt.subplot(number)

plt.title(list(df)[i])

ax1.scatter(df[df.columns[i]],y) #Plot a scatter draw of the

datapoints

plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)

# Split the datasets

X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y,

test_size=0.25)

# Scale the data for convergency optimization

scaler = preprocessing.StandardScaler()

# Set the transform parameters

X_train = scaler.fit_transform(X_train)

# Build a 2 layer fully connected DNN with 10 and 5 units respectively

regressor = skflow.TensorFlowDNNRegressor(hidden_units=[10, 5],

steps=500, learning_rate=0.051, batch_size=1)

# Fit the regressor

regressor.fit(X_train, y_train)

# Get some metrics based on the X and Y test data

score =

metrics.mean_squared_error(regressor.predict(scaler.transform(X_test)),

y_test)

print(" Total Mean Squared Error: " + str(score))

5.4 例3——多类分类:葡萄酒分类

本部分,我们会处理一个更复杂的数据集,预测葡萄酒的原产地。

5.4.1 数据集描述和加载

这个数据集包含了3种不同起源的葡萄酒,每个数据有13个属性。这些葡萄酒都由意大利制造,但是原产地不一样。

数据变量:

Alcohol:酒精度。

Malic acid:苹果酸。

Ash:灰。

Alcalinity of ash:灰分的碱度。

Magnesium:镁含量。

Total phenols:总酚类。

Flavanoids:黄烷类。

Nonflavanoid phenols:非类黄烷酚。

Proanthocyanins:原花青素。

Color intensity:颜色强度。

Hue:色相。

OD280/OD315 of diluted wines:稀释葡萄酒的OD280 / OD315。

Proline:脯氨酸。

读取该数据集,我们只需要调用pandas库即可。

df = pd.read_csv("./wine.csv", header=0)

5.4.2 数据集预处理

因为该csv文件从1开始,为数据减去该偏差:

y = df['Wine'].values-1

对于其结果,我们使用一位有效编码:

Y = tf.one_hot(indices = y, depth=3, on_value = 1., off_value = 0., axis =

1 , name = "a").eval()

不同变量跟原产地关系散点图如图5-7所示。同样,我们会选择预先打乱数据:

图5-7 不同变量跟原产地关系散点图

X, Y = shuffle (X, Y)

scaler = preprocessing.StandardScaler()

X = scaler.fit_transform(X)

5.4.3 模型架构

该模型只需要一个单层的全链接神经网络:

x = tf.placeholder(tf.float32, [None, 12])。

W = tf.Variable(tf.zeros([12, 3]))。

b = tf.Variable(tf.zeros([3]))。

5.4.4 损失函数描述

我们选择交叉熵作为损失函数:

y_ = tf.placeholder(tf.float32, [None, 3])

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y),

reduction_indices=[1]))

5.4.5 损失函数优化器

我们又一次选择梯度下降作为损失函数的优化器。

train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy)

5.4.6 收敛性测试

在收敛性测试中,我们将正确预测的结果算作1,错误预测的结果算作0,计算它们的均值,作为该模型的准确度。

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

print(accuracy.eval())

5.4.7 结果描述

正如我们所见,准确度会随着迭代的次数而波动,但一直是一个大于90%的准确率,远高于30%的基准线(如果我们随机猜测一个0~3的结果)。

0.973684

0.921053

0.921053

0.947368

0.921053

5.4.8 完整源代码

完整源代码如下:

sess = tf.InteractiveSession()

import pandas as pd

# Import data

from sklearn.utils import shuffle

from sklearn import preprocessing

flags = tf.app.flags

FLAGS = flags.FLAGS

df = pd.read_csv("./wine.csv", header=0)

print (df.describe())

#df['displacement']=df['displacement'].astype(float)

X = df[df.columns[1:13]].values

y = df['Wine'].values-1

Y = tf.one_hot(indices = y, depth=3, on_value = 1., off_value = 0., axis =

1 , name = "a").eval()

X, Y = shuffle (X, Y)

scaler = preprocessing.StandardScaler()

X = scaler.fit_transform(X)

# Create the model

x = tf.placeholder(tf.float32, [None, 12])

W = tf.Variable(tf.zeros([12, 3]))

b = tf.Variable(tf.zeros([3]))

# Define loss and optimizer

y_ = tf.placeholder(tf.float32, [None, 3])

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y),

reduction_indices=[1]))

train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy)

# Train

tf.initialize_all_variables().run()

for i in range(100):

X,Y =shuffle (X, Y, random_state=1)

Xtr=X[0:140,:]

Ytr=Y[0:140,:]

Xt=X[140:178,:]

Yt=Y[140:178,:]

Xtr, Ytr = shuffle (Xtr, Ytr, random_state=0)

batch_xs, batch_ys = Xtr , Ytr

train_step.run()

cost = sess.run (cross_entropy, feed_dict=)

# Test trained model

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

print(accuracy.eval())

5.5 小结

在本章中,我们开始学习TensorFlow最强的功能:神经网络模型。

通过使用生成模型和实验模型,我们同时实现了神经网络的回归和分类。

在下一章中,我们将会深入新的模型结构,并且将神经网络模型用到其他的知识领域,如将卷积神经网络用于计算机视觉。

-

本文摘自《TensorFlow机器学习项目实战》

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171228A07DKD00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券