Machine-Learning-Mastery-Keras-深度学习教程-六-

51 阅读1小时+

Machine Learning Mastery Keras 深度学习教程(六)

原文:Machine Learning Mastery

协议:CC BY-NC-SA 4.0

为癌症存活数据集开发神经网络

原文:machinelearningmastery.com/neural-netw…

为新数据集开发神经网络预测模型可能具有挑战性。

一种方法是首先检查数据集,并为哪些模型可能起作用提出想法,然后探索数据集上简单模型的学习动态,最后利用强大的测试工具为数据集开发和调整模型。

该过程可用于开发用于分类和回归预测建模问题的有效神经网络模型。

在本教程中,您将发现如何为癌症存活二元分类数据集开发多层感知机神经网络模型。

完成本教程后,您将知道:

  • 如何加载和总结癌症存活数据集,并使用结果建议数据准备和模型配置使用。
  • 如何探索数据集上简单 MLP 模型的学习动态。
  • 如何对模型表现进行稳健的估计,调整模型表现并对新数据进行预测。

我们开始吧。

Develop a Neural Network for Cancer Survival Dataset

为癌症存活数据集开发神经网络 图片由贝恩德·泰勒提供,保留部分权利。

教程概述

本教程分为 4 个部分;它们是:

  1. 哈贝曼乳腺癌存活数据集
  2. 神经网络学习动力学
  3. 稳健模型评估
  4. 最终模型和做出预测

哈贝曼乳腺癌存活数据集

第一步是定义和探索数据集。

我们将使用“哈贝曼”标准二进制分类数据集。

数据集描述了乳腺癌患者数据,结果是患者存活率。具体来说,患者是否存活了 5 年或更长时间,或者患者是否没有存活。

这是一个用于不平衡分类研究的标准数据集。根据数据集描述,手术于 1958 年至 1970 年在芝加哥大学比林斯医院进行。

数据集中有 306 个例子,有 3 个输入变量;它们是:

  • 手术时患者的年龄。
  • 运营的两位数年份。
  • 检测到的“阳性腋窝淋巴结的数量,这是衡量癌症是否已经扩散的指标。

因此,除了数据集中可用的情况之外,我们无法控制组成数据集的情况或在这些情况下使用的要素的选择。

尽管数据集描述了乳腺癌患者的存活率,但鉴于数据集规模较小,并且数据基于几十年前的乳腺癌诊断和手术,因此任何基于该数据集构建的模型都不可一概而论。

注:说得再清楚不过了,我们是不是“解决乳腺癌”。我们正在探索一个标准的分类数据集。

下面是数据集前 5 行的示例

30,64,1,1
30,62,3,1
30,65,0,1
31,59,2,1
31,65,4,1
...

您可以在此了解有关数据集的更多信息:

我们可以直接从网址将数据集加载为熊猫数据帧;例如:

# load the haberman dataset and summarize the shape
from pandas import read_csv
# define the location of the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/haberman.csv'
# load the dataset
df = read_csv(url, header=None)
# summarize shape
print(df.shape)

运行该示例直接从 URL 加载数据集,并报告数据集的形状。

在这种情况下,我们可以确认数据集有 4 个变量(3 个输入和 1 个输出),并且数据集有 306 行数据。

对于神经网络来说,这不是很多行的数据,这表明一个小的网络,也许带有正则化,将是合适的。

它还建议使用 k 倍交叉验证将是一个好主意,因为它将给出比训练/测试分割更可靠的模型表现估计,并且因为单个模型将在几秒钟内适合最大数据集,而不是几小时或几天。

(306, 4)

接下来,我们可以通过查看汇总统计数据和数据图来了解更多关于数据集的信息。

# show summary statistics and plots of the haberman dataset
from pandas import read_csv
from matplotlib import pyplot
# define the location of the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/haberman.csv'
# load the dataset
df = read_csv(url, header=None)
# show summary statistics
print(df.describe())
# plot histograms
df.hist()
pyplot.show()

运行该示例首先加载之前的数据,然后打印每个变量的汇总统计信息。

我们可以看到,数值随着不同的平均值和标准偏差而变化,也许在建模之前需要一些规范化或标准化。

                0           1           2           3
count  306.000000  306.000000  306.000000  306.000000
mean    52.457516   62.852941    4.026144    1.264706
std     10.803452    3.249405    7.189654    0.441899
min     30.000000   58.000000    0.000000    1.000000
25%     44.000000   60.000000    0.000000    1.000000
50%     52.000000   63.000000    1.000000    1.000000
75%     60.750000   65.750000    4.000000    2.000000
max     83.000000   69.000000   52.000000    2.000000

然后为每个变量创建直方图。

我们可以看到,也许第一个变量具有类高斯分布,接下来的两个输入变量可能具有指数分布。

我们在每个变量上使用幂变换可能会有一些好处,以便使概率分布不那么偏斜,这可能会提高模型表现。

Histograms of the Haberman Breast Cancer Survival Classification Dataset

哈贝曼乳腺癌存活分类数据集的直方图

我们可以看到两个类之间的例子分布有些偏斜,这意味着分类问题是不平衡的。这是不平衡的。

了解数据集实际上有多不平衡可能会有所帮助。

我们可以使用 Counter 对象来统计每个类中的示例数量,然后使用这些计数来总结分布。

下面列出了完整的示例。

# summarize the class ratio of the haberman dataset
from pandas import read_csv
from collections import Counter
# define the location of the dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/haberman.csv'
# define the dataset column names
columns = ['age', 'year', 'nodes', 'class']
# load the csv file as a data frame
dataframe = read_csv(url, header=None, names=columns)
# summarize the class distribution
target = dataframe['class'].values
counter = Counter(target)
for k,v in counter.items():
	per = v / len(target) * 100
	print('Class=%d, Count=%d, Percentage=%.3f%%' % (k, v, per))

运行该示例总结了数据集的类分布。

我们可以看到存活类 1 在 225 处有最多的例子,大约占数据集的 74%。我们可以看到非存活类 2 的例子更少,只有 81 个,约占数据集的 26%。

阶级分布是倾斜的,但并不严重不平衡。

Class=1, Count=225, Percentage=73.529%
Class=2, Count=81, Percentage=26.471%

这是有帮助的,因为如果我们使用分类精确率,那么任何达到低于约 73.5%精确率的模型都不具备在这个数据集上的技能。

现在我们已经熟悉了数据集,让我们探索如何开发一个神经网络模型。

神经网络学习动力学

我们将使用张量流为数据集开发一个多层感知机(MLP)模型。

我们无法知道什么样的学习超参数的模型架构对这个数据集是好的或最好的,所以我们必须实验并发现什么是好的。

假设数据集很小,小批量可能是个好主意,例如 16 或 32 行。开始时使用亚当版本的随机梯度下降是一个好主意,因为它会自动调整学习速率,并且在大多数数据集上运行良好。

在我们认真评估模型之前,最好回顾学习动态,调整模型架构和学习配置,直到我们有稳定的学习动态,然后看看如何从模型中获得最大收益。

我们可以通过使用简单的数据训练/测试分割和学习曲线的回顾图来做到这一点。这将有助于我们了解自己是学习过度还是学习不足;然后我们可以相应地调整配置。

首先,我们必须确保所有输入变量都是浮点值,并将目标标签编码为整数值 0 和 1。

...
# ensure all data are floating point values
X = X.astype('float32')
# encode strings to integer
y = LabelEncoder().fit_transform(y)

接下来,我们可以将数据集分成输入和输出变量,然后分成 67/33 训练集和测试集。

我们必须确保按类对拆分进行分层,确保训练集和测试集具有与主数据集相同的类标签分布。

...
# split into input and output columns
X, y = df.values[:, :-1], df.values[:, -1]
# split into train and test datasets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, stratify=y, random_state=3)

我们可以定义一个最小 MLP 模型。在这种情况下,我们将使用一个具有 10 个节点的隐藏层和一个输出层(任意选择)。我们将使用隐藏层中的 ReLU 激活函数he _ normal权重初始化,作为一个整体,它们是一个很好的练习。

模型的输出是二进制分类的 sigmoid 激活,我们将最小化二进制交叉熵损失

...
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy')

我们将使模型适合 200 个训练时期(任意选择),批量大小为 16,因为它是一个小数据集。

我们正在原始数据上拟合模型,我们认为这可能是一个好主意,但这是一个重要的起点。

...
# fit the model
history = model.fit(X_train, y_train, epochs=200, batch_size=16, verbose=0, validation_data=(X_test,y_test))

在训练结束时,我们将评估模型在测试数据集上的表现,并将表现报告为分类精确率。

...
# predict test set
yhat = model.predict_classes(X_test)
# evaluate predictions
score = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % score)

最后,我们将绘制训练和测试集上交叉熵损失的学习曲线。

...
# plot learning curves
pyplot.title('Learning Curves')
pyplot.xlabel('Epoch')
pyplot.ylabel('Cross Entropy')
pyplot.plot(history.history['loss'], label='train')
pyplot.plot(history.history['val_loss'], label='val')
pyplot.legend()
pyplot.show()

将所有这些结合起来,下面列出了在癌症存活数据集上评估我们的第一个 MLP 的完整示例。

# fit a simple mlp model on the haberman and review learning curves
from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from matplotlib import pyplot
# load the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/haberman.csv'
df = read_csv(path, header=None)
# split into input and output columns
X, y = df.values[:, :-1], df.values[:, -1]
# ensure all data are floating point values
X = X.astype('float32')
# encode strings to integer
y = LabelEncoder().fit_transform(y)
# split into train and test datasets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, stratify=y, random_state=3)
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy')
# fit the model
history = model.fit(X_train, y_train, epochs=200, batch_size=16, verbose=0, validation_data=(X_test,y_test))
# predict test set
yhat = model.predict_classes(X_test)
# evaluate predictions
score = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % score)
# plot learning curves
pyplot.title('Learning Curves')
pyplot.xlabel('Epoch')
pyplot.ylabel('Cross Entropy')
pyplot.plot(history.history['loss'], label='train')
pyplot.plot(history.history['val_loss'], label='val')
pyplot.legend()
pyplot.show()

运行该示例首先在训练数据集上拟合模型,然后在测试数据集上报告分类精确率。

用我的新书机器学习的数据准备启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

在这种情况下,我们可以看到该模型比无技能模型表现得更好,假设准确率在 73.5%以上。

Accuracy: 0.765

然后创建列车和测试集上的损耗线图。

我们可以看到,模型很快在数据集上找到了一个很好的拟合,并且看起来没有过度拟合或拟合不足。

Learning Curves of Simple Multilayer Perceptron on Cancer Survival Dataset

癌症存活数据集上简单多层感知机的学习曲线

现在,我们已经对数据集上的简单 MLP 模型的学习动态有了一些了解,我们可以考虑对数据集上的模型表现进行更稳健的评估。

稳健模型评估

k 倍交叉验证程序可以提供更可靠的 MLP 表现估计,尽管它可能非常慢。

这是因为 k 模型必须被拟合和评估。当数据集规模较小时,例如癌症存活数据集,这不是问题。

我们可以使用stratifiedfold类手动枚举每个折叠,拟合模型,对其进行评估,然后在程序结束时报告评估分数的平均值。

...
# prepare cross validation
kfold = KFold(10)
# enumerate splits
scores = list()
for train_ix, test_ix in kfold.split(X, y):
	# fit and evaluate the model...
	...
...
# summarize all scores
print('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

我们可以使用这个框架,利用我们的基本配置,甚至利用一系列不同的数据准备、模型架构和学习配置,来开发 MLP 模型表现的可靠估计。

重要的是,在使用 k-fold 交叉验证来估计表现之前,我们首先了解了上一节中模型在数据集上的学习动态。如果我们开始直接调整模型,我们可能会得到好的结果,但如果没有,我们可能不知道为什么,例如,模型过度或拟合不足。

如果我们再次对模型进行大的更改,最好返回并确认模型正在适当收敛。

下面列出了评估前一节中的基本 MLP 模型的框架的完整示例。

# k-fold cross-validation of base model for the haberman dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.model_selection import StratifiedKFold
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from matplotlib import pyplot
# load the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/haberman.csv'
df = read_csv(path, header=None)
# split into input and output columns
X, y = df.values[:, :-1], df.values[:, -1]
# ensure all data are floating point values
X = X.astype('float32')
# encode strings to integer
y = LabelEncoder().fit_transform(y)
# prepare cross validation
kfold = StratifiedKFold(10, random_state=1)
# enumerate splits
scores = list()
for train_ix, test_ix in kfold.split(X, y):
	# split data
	X_train, X_test, y_train, y_test = X[train_ix], X[test_ix], y[train_ix], y[test_ix]
	# determine the number of input features
	n_features = X.shape[1]
	# define model
	model = Sequential()
	model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
	model.add(Dense(1, activation='sigmoid'))
	# compile the model
	model.compile(optimizer='adam', loss='binary_crossentropy')
	# fit the model
	model.fit(X_train, y_train, epochs=200, batch_size=16, verbose=0)
	# predict test set
	yhat = model.predict_classes(X_test)
	# evaluate predictions
	score = accuracy_score(y_test, yhat)
	print('>%.3f' % score)
	scores.append(score)
# summarize all scores
print('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

运行该示例会报告评估程序每次迭代的模型表现,并在运行结束时报告分类精确率的平均值和标准偏差。

用我的新书机器学习的数据准备启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

在这种情况下,我们可以看到 MLP 模型获得了大约 75.2%的平均精确率,这与我们在前面部分中的粗略估计非常接近。

这证实了我们的预期,即对于这个数据集,基本模型配置可能比简单模型工作得更好

>0.742
>0.774
>0.774
>0.806
>0.742
>0.710
>0.767
>0.800
>0.767
>0.633
Mean Accuracy: 0.752 (0.048)

这是个好结果吗?

事实上,这是一个具有挑战性的分类问题,达到 74.5%以上的分数是好的。

接下来,让我们看看如何拟合最终模型并使用它进行预测。

最终模型和做出预测

一旦我们选择了一个模型配置,我们就可以在所有可用的数据上训练一个最终模型,并使用它来对新数据进行预测。

在这种情况下,我们将使用具有脱落和小批量的模型作为最终模型。

我们可以像以前一样准备数据并拟合模型,尽管是在整个数据集上,而不是数据集的训练子集上。

...
# split into input and output columns
X, y = df.values[:, :-1], df.values[:, -1]
# ensure all data are floating point values
X = X.astype('float32')
# encode strings to integer
le = LabelEncoder()
y = le.fit_transform(y)
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy')

然后,我们可以使用这个模型对新数据进行预测。

首先,我们可以定义一行新数据。

...
# define a row of new data
row = [30,64,1]

注意:我从数据集的第一行提取了这一行,预期的标签是“1”。

然后我们可以做一个预测。

...
# make prediction
yhat = model.predict_classes([row])

然后反转预测上的转换,这样我们就可以使用或解释正确标签中的结果(对于这个数据集,它只是一个整数)。

...
# invert transform to get label for class
yhat = le.inverse_transform(yhat)

在这种情况下,我们将简单地报告预测。

...
# report prediction
print('Predicted: %s' % (yhat[0]))

将所有这些结合起来,下面列出了为 haberman 数据集拟合最终模型并使用它对新数据进行预测的完整示例。

# fit a final model and make predictions on new data for the haberman dataset
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Dropout
# load the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/haberman.csv'
df = read_csv(path, header=None)
# split into input and output columns
X, y = df.values[:, :-1], df.values[:, -1]
# ensure all data are floating point values
X = X.astype('float32')
# encode strings to integer
le = LabelEncoder()
y = le.fit_transform(y)
# determine the number of input features
n_features = X.shape[1]
# define model
model = Sequential()
model.add(Dense(10, activation='relu', kernel_initializer='he_normal', input_shape=(n_features,)))
model.add(Dense(1, activation='sigmoid'))
# compile the model
model.compile(optimizer='adam', loss='binary_crossentropy')
# fit the model
model.fit(X, y, epochs=200, batch_size=16, verbose=0)
# define a row of new data
row = [30,64,1]
# make prediction
yhat = model.predict_classes([row])
# invert transform to get label for class
yhat = le.inverse_transform(yhat)
# report prediction
print('Predicted: %s' % (yhat[0]))

运行该示例使模型适合整个数据集,并对单行新数据进行预测。

用我的新书机器学习的数据准备启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

在这种情况下,我们可以看到模型为输入行预测了一个“1”标签。

Predicted: 1

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

教程

摘要

在本教程中,您发现了如何为癌症存活二元分类数据集开发多层感知机神经网络模型。

具体来说,您了解到:

  • 如何加载和总结癌症存活数据集,并使用结果建议数据准备和模型配置使用。
  • 如何探索数据集上简单 MLP 模型的学习动态。
  • 如何对模型表现进行稳健的估计,调整模型表现并对新数据进行预测。

你有什么问题吗? 在下面的评论中提问,我会尽力回答。

用于组合分类和回归的神经网络模型

原文:machinelearningmastery.com/neural-netw…

一些预测问题需要预测相同输入的数值和类别标签。

一个简单的方法是在相同的数据上开发回归和分类预测模型,并按顺序使用这些模型。

另一种通常更有效的方法是开发一个单一的神经网络模型,该模型可以从同一输入中预测数值和类别标签值。这被称为多输出模型,使用现代深度学习库如 Keras 和 TensorFlow 可以相对容易地开发和评估。

在本教程中,您将发现如何开发用于组合回归和分类预测的神经网络。

完成本教程后,您将知道:

  • 有些预测问题需要预测每个输入示例的数值和类别标签值。
  • 如何为需要多个输出的问题开发单独的回归和分类模型?
  • 如何开发和评估能够同时进行回归和分类预测的神经网络模型?

我们开始吧。

Develop Neural Network for Combined Classification and Regression

开发用于组合分类和回归的神经网络 图片由桑特林提供,保留部分权利。

教程概述

本教程分为三个部分;它们是:

  1. 回归和分类的单一模型
  2. 分离回归和分类模型
    1. 鲍鱼数据集
    2. 回归模型
    3. 分类模型
  3. 组合回归和分类模型

回归和分类的单一模型

为回归或分类问题开发深度学习神经网络模型是很常见的,但是在一些预测建模任务中,我们可能希望开发一个既能进行回归预测又能进行分类预测的单一模型。

回归是指预测建模问题,包括预测给定输入的数值。

分类指的是预测建模问题,包括预测给定输入的类别标签或类别标签的概率。

有关分类和回归之间区别的更多信息,请参见教程:

可能会有一些问题,我们希望预测一个数值和一个分类值。

解决这个问题的一种方法是为每个需要的预测开发一个单独的模型。

这种方法的问题在于,不同模型做出的预测可能会有所不同。

在使用神经网络模型时,可以使用的另一种方法是开发一个单一模型,该模型能够对同一输入的数值和类别输出进行单独预测。

这被称为多输出神经网络模型。

这种类型的模型的好处是,我们有一个单一的模型来开发和维护,而不是两个模型,同时在两种输出类型上训练和更新模型可能会在两种输出类型之间的预测中提供更多的一致性。

我们将开发一个能够同时进行回归和分类预测的多输出神经网络模型。

首先,让我们选择一个有意义的数据集,并从为回归和分类预测开发单独的模型开始。

分离回归和分类模型

在这一节中,我们将从选择一个真实的数据集开始,在那里我们可能同时需要回归和分类预测,然后为每种类型的预测开发单独的模型。

鲍鱼数据集

我们将使用“鲍鱼”数据集。

确定鲍鱼的年龄是一项耗时的任务,仅从身体细节来确定年龄是可取的。

这是一个描述鲍鱼的物理细节的数据集,需要预测鲍鱼的环数,这是这种生物年龄的代理。

您可以从这里了解有关数据集的更多信息:

年龄”既可以作为数值(以年为单位)预测,也可以作为类别标签(以序数年为类别)预测。

不需要下载数据集,因为我们将自动下载它作为工作示例的一部分。

数据集提供了一个数据集示例,我们可能需要输入的数字和分类。

首先,让我们开发一个下载和总结数据集的示例。

# load and summarize the abalone dataset
from pandas import read_csv
from matplotlib import pyplot
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'
dataframe = read_csv(url, header=None)
# summarize shape
print(dataframe.shape)
# summarize first few lines
print(dataframe.head())

运行该示例首先下载并总结数据集的形状。

我们可以看到,有 4,177 个例子(行)可以用来训练和评估一个模型,以及包括目标变量在内的 9 个特性(列)。

我们可以看到所有的输入变量都是数字,除了第一个,它是一个字符串值。

为了简化数据准备,我们将从模型中删除第一列,并将重点放在数字输入值的建模上。

(4177, 9)
   0      1      2      3       4       5       6      7   8
0  M  0.455  0.365  0.095  0.5140  0.2245  0.1010  0.150  15
1  M  0.350  0.265  0.090  0.2255  0.0995  0.0485  0.070   7
2  F  0.530  0.420  0.135  0.6770  0.2565  0.1415  0.210   9
3  M  0.440  0.365  0.125  0.5160  0.2155  0.1140  0.155  10
4  I  0.330  0.255  0.080  0.2050  0.0895  0.0395  0.055   7

我们可以使用这些数据作为开发单独的回归和分类多层感知机(MLP)神经网络模型的基础。

:我们并不是试图为此数据集开发一个最优模型;相反,我们正在演示一种特定的技术:开发一个可以进行回归和分类预测的模型。

回归模型

在本节中,我们将为鲍鱼数据集开发一个回归 MLP 模型。

首先,我们必须将列分成输入和输出元素,并删除包含字符串值的第一列。

我们还将强制所有加载的列具有浮点类型(神经网络模型所期望的),并记录输入特征的数量,这将需要由模型稍后知道。

...
# split into input (X) and output (y) variables
X, y = dataset[:, 1:-1], dataset[:, -1]
X, y = X.astype('float'), y.astype('float')
n_features = X.shape[1]

接下来,我们可以将数据集分割成一个训练和测试数据集。

我们将使用 67%的随机样本来训练模型,剩下的 33%用于评估模型。

...
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)

然后我们可以定义一个 MLP 神经网络模型。

模型将有两个隐藏层,第一个有 20 个节点,第二个有 10 个节点,都使用 ReLU 激活he normal权重初始化(很好的做法)。层数和节点数是任意选择的。

输出层将有一个用于预测数值的节点和一个线性激活函数。

...
# define the keras model
model = Sequential()
model.add(Dense(20, input_dim=n_features, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(10, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1, activation='linear'))

该模型将被训练为使用随机梯度下降的有效亚当版本来最小化均方误差损失函数。

...
# compile the keras model
model.compile(loss='mse', optimizer='adam')

我们将用 32 个样本的小批量为 150 个时代训练模型,同样是任意选择的。

...
# fit the keras model on the dataset
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=2)

最后,在训练模型后,我们将在保持测试数据集上对其进行评估,并报告平均绝对误差(MAE)。

...
# evaluate on test set
yhat = model.predict(X_test)
error = mean_absolute_error(y_test, yhat)
print('MAE: %.3f' % error)

将所有这些联系在一起,鲍鱼数据集的 MLP 神经网络的完整示例被框定为回归问题,如下所示。

# regression mlp model for the abalone dataset
from pandas import read_csv
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.metrics import mean_absolute_error
from sklearn.model_selection import train_test_split
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'
dataframe = read_csv(url, header=None)
dataset = dataframe.values
# split into input (X) and output (y) variables
X, y = dataset[:, 1:-1], dataset[:, -1]
X, y = X.astype('float'), y.astype('float')
n_features = X.shape[1]
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# define the keras model
model = Sequential()
model.add(Dense(20, input_dim=n_features, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(10, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(1, activation='linear'))
# compile the keras model
model.compile(loss='mse', optimizer='adam')
# fit the keras model on the dataset
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=2)
# evaluate on test set
yhat = model.predict(X_test)
error = mean_absolute_error(y_test, yhat)
print('MAE: %.3f' % error)

运行该示例将准备数据集,拟合模型,并报告模型误差的估计值。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到模型实现了大约 1.5(环)的误差。

...
Epoch 145/150
88/88 - 0s - loss: 4.6130
Epoch 146/150
88/88 - 0s - loss: 4.6182
Epoch 147/150
88/88 - 0s - loss: 4.6277
Epoch 148/150
88/88 - 0s - loss: 4.6437
Epoch 149/150
88/88 - 0s - loss: 4.6166
Epoch 150/150
88/88 - 0s - loss: 4.6132
MAE: 1.554

目前为止一切顺利。

接下来,让我们看看开发一个类似的分类模型。

分类模型

鲍鱼数据集可以被构建为一个分类问题,其中每个“”整数被视为一个单独的类标签。

示例和模型与上面的回归示例基本相同,只是有一些重要的变化。

这需要首先为每个“值分配一个单独的整数,从 0 开始,以“的总数减 1 结束。

这可以通过标签编码器来实现。

我们还可以将类的总数记录为唯一编码类值的总数,这将是模型稍后需要的。

...
# encode strings to integer
y = LabelEncoder().fit_transform(y)
n_class = len(unique(y))

像以前一样将数据拆分为训练集和测试集后,我们可以定义模型,并将模型的输出数量更改为等于类的数量,并使用多类分类通用的 softmax 激活函数。

...
# define the keras model
model = Sequential()
model.add(Dense(20, input_dim=n_features, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(10, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(n_class, activation='softmax'))

假设我们已经将类标签编码为整数值,我们可以通过最小化稀疏分类交叉熵损失函数来拟合模型,适用于具有整数编码类标签的多类分类任务。

...
# compile the keras model
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')

如前所述,在将模型拟合到训练数据集上之后,我们可以通过计算保持测试集上的分类精确率来评估模型的表现。

...
# evaluate on test set
yhat = model.predict(X_test)
yhat = argmax(yhat, axis=-1).astype('int')
acc = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % acc)

将所有这些结合起来,下面列出了鲍鱼数据集的 MLP 神经网络作为分类问题的完整示例。

# classification mlp model for the abalone dataset
from numpy import unique
from numpy import argmax
from pandas import read_csv
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'
dataframe = read_csv(url, header=None)
dataset = dataframe.values
# split into input (X) and output (y) variables
X, y = dataset[:, 1:-1], dataset[:, -1]
X, y = X.astype('float'), y.astype('float')
n_features = X.shape[1]
# encode strings to integer
y = LabelEncoder().fit_transform(y)
n_class = len(unique(y))
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# define the keras model
model = Sequential()
model.add(Dense(20, input_dim=n_features, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(10, activation='relu', kernel_initializer='he_normal'))
model.add(Dense(n_class, activation='softmax'))
# compile the keras model
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')
# fit the keras model on the dataset
model.fit(X_train, y_train, epochs=150, batch_size=32, verbose=2)
# evaluate on test set
yhat = model.predict(X_test)
yhat = argmax(yhat, axis=-1).astype('int')
acc = accuracy_score(y_test, yhat)
print('Accuracy: %.3f' % acc)

运行该示例将准备数据集,拟合模型,并报告模型误差的估计值。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到模型达到了大约 27%的准确率。

...
Epoch 145/150
88/88 - 0s - loss: 1.9271
Epoch 146/150
88/88 - 0s - loss: 1.9265
Epoch 147/150
88/88 - 0s - loss: 1.9265
Epoch 148/150
88/88 - 0s - loss: 1.9271
Epoch 149/150
88/88 - 0s - loss: 1.9262
Epoch 150/150
88/88 - 0s - loss: 1.9260
Accuracy: 0.274

目前为止一切顺利。

接下来,让我们看看开发一个能够进行回归和分类预测的组合模型。

组合回归和分类模型

在这一部分,我们可以开发一个单一的 MLP 神经网络模型,可以对单一输入进行回归和分类预测。

这被称为多输出模型,可以使用功能性的 Keras API 进行开发。

关于这个函数式 API 的更多信息,对于初学者来说可能很棘手,请参见教程:

首先,必须准备好数据集。

我们可以像以前一样准备数据集进行分类,尽管我们应该用单独的名称保存编码的目标变量,以将其与原始目标变量值区分开来。

...
# encode strings to integer
y_class = LabelEncoder().fit_transform(y)
n_class = len(unique(y_class))

然后,我们可以将输入、原始输出和编码输出变量分成训练集和测试集。

...
# split data into train and test sets
X_train, X_test, y_train, y_test, y_train_class, y_test_class = train_test_split(X, y, y_class, test_size=0.33, random_state=1)

接下来,我们可以使用功能 API 来定义模型。

该模型采用与独立模型相同数量的输入,并使用以相同方式配置的两个隐藏层。

...
# input
visible = Input(shape=(n_features,))
hidden1 = Dense(20, activation='relu', kernel_initializer='he_normal')(visible)
hidden2 = Dense(10, activation='relu', kernel_initializer='he_normal')(hidden1)

然后,我们可以定义两个独立的输出层,它们连接到模型的第二个隐藏层。

第一个是回归输出层,具有单个节点和线性激活函数。

...
# regression output
out_reg = Dense(1, activation='linear')(hidden2)

第二个是分类输出层,每个被预测的类有一个节点,并使用 softmax 激活函数。

...
# classification output
out_clas = Dense(n_class, activation='softmax')(hidden2)

然后,我们可以用一个输入层和两个输出层来定义模型。

...
# define model
model = Model(inputs=visible, outputs=[out_reg, out_clas])

给定两个输出层,我们可以编译具有两个损失函数的模型,第一(回归)输出层的均方误差损失和第二(分类)输出层的稀疏分类交叉熵。

...
# compile the keras model
model.compile(loss=['mse','sparse_categorical_crossentropy'], optimizer='adam')

我们也可以创建一个模型图作为参考。

这要求安装 pydot 和 pygraphviz。如果这是一个问题,您可以注释掉这一行和 plot_model() 函数的导入语句。

...
# plot graph of model
plot_model(model, to_file='model.png', show_shapes=True)

模型每次做预测,都会预测两个值。

类似地,当训练模型时,对于每个输出,每个样本需要一个目标变量。

因此,我们可以训练模型,小心地为模型的每个输出提供回归目标和分类目标数据。

...
# fit the keras model on the dataset
model.fit(X_train, [y_train,y_train_class], epochs=150, batch_size=32, verbose=2)

然后,拟合模型可以对搁置测试集中的每个示例进行回归和分类预测。

...
# make predictions on test set
yhat1, yhat2 = model.predict(X_test)

第一个数组可用于通过平均绝对误差评估回归预测。

...
# calculate error for regression model
error = mean_absolute_error(y_test, yhat1)
print('MAE: %.3f' % error)

第二阵列可用于通过分类精确率评估分类预测。

...
# evaluate accuracy for classification model
yhat2 = argmax(yhat2, axis=-1).astype('int')
acc = accuracy_score(y_test_class, yhat2)
print('Accuracy: %.3f' % acc)

就这样。

将这些结合起来,下面列出了在鲍鱼数据集上训练和评估用于组合器回归和分类预测的多输出模型的完整示例。

# mlp for combined regression and classification predictions on the abalone dataset
from numpy import unique
from numpy import argmax
from pandas import read_csv
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import plot_model
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'
dataframe = read_csv(url, header=None)
dataset = dataframe.values
# split into input (X) and output (y) variables
X, y = dataset[:, 1:-1], dataset[:, -1]
X, y = X.astype('float'), y.astype('float')
n_features = X.shape[1]
# encode strings to integer
y_class = LabelEncoder().fit_transform(y)
n_class = len(unique(y_class))
# split data into train and test sets
X_train, X_test, y_train, y_test, y_train_class, y_test_class = train_test_split(X, y, y_class, test_size=0.33, random_state=1)
# input
visible = Input(shape=(n_features,))
hidden1 = Dense(20, activation='relu', kernel_initializer='he_normal')(visible)
hidden2 = Dense(10, activation='relu', kernel_initializer='he_normal')(hidden1)
# regression output
out_reg = Dense(1, activation='linear')(hidden2)
# classification output
out_clas = Dense(n_class, activation='softmax')(hidden2)
# define model
model = Model(inputs=visible, outputs=[out_reg, out_clas])
# compile the keras model
model.compile(loss=['mse','sparse_categorical_crossentropy'], optimizer='adam')
# plot graph of model
plot_model(model, to_file='model.png', show_shapes=True)
# fit the keras model on the dataset
model.fit(X_train, [y_train,y_train_class], epochs=150, batch_size=32, verbose=2)
# make predictions on test set
yhat1, yhat2 = model.predict(X_test)
# calculate error for regression model
error = mean_absolute_error(y_test, yhat1)
print('MAE: %.3f' % error)
# evaluate accuracy for classification model
yhat2 = argmax(yhat2, axis=-1).astype('int')
acc = accuracy_score(y_test_class, yhat2)
print('Accuracy: %.3f' % acc)

运行该示例将准备数据集,拟合模型,并报告模型误差的估计值。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

创建多输出模型的图,清楚地显示连接到模型的第二个隐藏层的回归(左)和分类(右)输出层。

Plot of the Multi-Output Model for Combine Regression and Classification Predictions

用于组合回归和分类预测的多输出模型图

在这种情况下,我们可以看到该模型实现了大约 1.495(环)的合理误差和大约 25.6%的类似精确率。

...
Epoch 145/150
88/88 - 0s - loss: 6.5707 - dense_2_loss: 4.5396 - dense_3_loss: 2.0311
Epoch 146/150
88/88 - 0s - loss: 6.5753 - dense_2_loss: 4.5466 - dense_3_loss: 2.0287
Epoch 147/150
88/88 - 0s - loss: 6.5970 - dense_2_loss: 4.5723 - dense_3_loss: 2.0247
Epoch 148/150
88/88 - 0s - loss: 6.5640 - dense_2_loss: 4.5389 - dense_3_loss: 2.0251
Epoch 149/150
88/88 - 0s - loss: 6.6053 - dense_2_loss: 4.5827 - dense_3_loss: 2.0226
Epoch 150/150
88/88 - 0s - loss: 6.5754 - dense_2_loss: 4.5524 - dense_3_loss: 2.0230
MAE: 1.495
Accuracy: 0.256

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

教程

摘要

在本教程中,您发现了如何开发用于组合回归和分类预测的神经网络。

具体来说,您了解到:

  • 有些预测问题需要预测每个输入示例的数值和类别标签值。
  • 如何为需要多个输出的问题开发单独的回归和分类模型?
  • 如何开发和评估能够同时进行回归和分类预测的神经网络模型?

你有什么问题吗? 在下面的评论中提问,我会尽力回答。

神经网络是函数近似算法

原文:machinelearningmastery.com/neural-netw…

最后更新于 2020 年 8 月 27 日

机器学习中的监督学习可以用函数近似来描述。

给定一个由输入和输出组成的数据集,我们假设有一个未知的底层函数,它在目标域中将输入映射到输出并生成数据集时是一致的。然后我们使用监督学习算法来近似这个函数。

神经网络是有监督的机器学习算法的一个例子,也许在函数近似的背景下最容易理解。这可以通过神经网络近似简单的一维函数的例子来证明,这有助于培养对模型所学内容的直觉。

在本教程中,您将发现神经网络作为函数近似算法背后的直觉。

完成本教程后,您将知道:

  • 在数据上训练神经网络近似于从输入到输出的未知底层映射函数。
  • 一维输入输出数据集为开发函数近似的直观性提供了有用的基础。
  • 如何开发和评估用于函数近似的小型神经网络?

用我的新书用 Python 深度学习来启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

我们开始吧。

Neural Networks are Function Approximators

神经网络是函数近似算法 图片由达维宁提供,版权所有。

教程概述

本教程分为三个部分;它们是:

  1. 什么是函数近似
  2. 简单函数的定义
  3. 近似简单函数

什么是函数近似

函数近似是一种使用来自域的历史或可用观测值来估计未知基础函数的技术。

人工神经网络学习近似一个函数。

在监督学习中,数据集由输入和输出组成,监督学习算法学习如何最好地将输入示例映射到输出示例。

我们可以把这个映射看作是由一个数学函数支配的,这个函数叫做映射函数,监督学习算法试图最好地近似的就是这个函数。

神经网络是监督学习算法的一个例子,它试图近似你的数据所代表的函数。这是通过计算预测输出和预期输出之间的误差并在训练过程中最小化该误差来实现的。

最好将前馈网络视为功能近似机器,旨在实现统计泛化,偶尔从我们对大脑的了解中获得一些见解,而不是将其视为大脑功能的模型。

—第 169 页,深度学习,2016。

我们说“近似”是因为虽然我们怀疑这样的映射函数存在,但我们对此一无所知。

将输入映射到输出的真实函数是未知的,通常被称为目标函数。这是学习过程的目标,也是我们试图仅使用可用数据来近似的功能。如果我们知道目标函数,我们就不需要近似它,也就是说,我们不需要有监督的机器学习算法。因此,当底层目标映射函数未知时,函数近似只是一个有用的工具。

我们所拥有的只是来自包含输入和输出示例的领域的观察。这意味着数据的大小和质量;例如:

  • 我们拥有的例子越多,我们就越能理解映射函数。
  • 观测中的噪声越小,我们对映射函数的近似就越清晰。

那么为什么我们喜欢用神经网络进行函数近似呢?

原因是他们是通用近似器。理论上,它们可以用来近似任何函数。

……通用近似定理指出,具有线性输出层和至少一个具有任何“挤压”激活函数(如逻辑 sigmoid 激活函数)的隐藏层的前馈网络可以用任何期望的非零误差量近似从一个有限维空间到另一个有限维空间的任何[…]函数,前提是网络被给予足够的隐藏单元

—第 198 页,深度学习,2016。

回归预测建模包括预测给定输入的数值。分类预测建模包括预测给定输入的类别标签。

这两个预测建模问题都可以看作是函数近似的例子。

为了使这一点具体化,我们可以回顾一个工作的例子。

在下一节中,让我们定义一个简单的函数,稍后我们可以对其进行近似。

简单函数的定义

我们可以定义一个具有一个数值输入变量和一个数值输出变量的简单函数,并以此作为理解函数近似的神经网络的基础。

我们可以定义一个数字域作为我们的输入,比如从-50 到 50 的浮点值。

然后,我们可以选择一个数学运算应用于输入,以获得输出值。选择的数学运算将是映射函数,因为我们正在选择它,所以我们将知道它是什么。实际上,情况并非如此,这就是为什么我们会使用像神经网络这样的监督学习算法来学习或发现映射函数。

在这种情况下,我们将使用输入的平方作为映射函数,定义为:

  • y = x²

其中 y 为输出变量, x 为输入变量。

我们可以通过枚举输入变量范围内的值,计算每个输入的输出值并绘制结果,来为这个映射函数开发一种直觉。

下面的例子用 Python 实现了这一点。

# example of creating a univariate dataset with a given mapping function
from matplotlib import pyplot
# define the input data
x = [i for i in range(-50,51)]
# define the output data
y = [i**2.0 for i in x]
# plot the input versus the output
pyplot.scatter(x,y)
pyplot.title('Input (x) versus Output (y)')
pyplot.xlabel('Input Variable (x)')
pyplot.ylabel('Output Variable (y)')
pyplot.show()

运行该示例首先在整个输入域中创建一个整数值列表。

然后使用映射函数计算输出值,然后用 x 轴上的输入值和 y 轴上的输出值创建一个图。

Scatter Plot of Input and Output Values for the Chosen Mapping Function

所选映射函数的输入和输出值散点图

输入和输出变量代表我们的数据集。

接下来,我们可以假装忘记我们知道映射函数是什么,并使用神经网络来重新学习或重新发现映射函数。

近似简单函数

我们可以在输入和输出的例子上拟合神经网络模型,看看该模型是否能够学习映射函数。

这是一个非常简单的映射函数,所以我们希望一个小的神经网络可以快速学习它。

我们将使用 Keras 深度学习库定义网络,并使用 Sklearn 库中的一些数据准备工具。

首先,让我们定义数据集。

...
# define the dataset
x = asarray([i for i in range(-50,51)])
y = asarray([i**2.0 for i in x])
print(x.min(), x.max(), y.min(), y.max())

接下来,我们可以重塑数据,使输入和输出变量是每行一个观察值的列,正如使用监督学习模型时所预期的那样。

...
# reshape arrays into into rows and cols
x = x.reshape((len(x), 1))
y = y.reshape((len(y), 1))

接下来,我们需要缩放输入和输出。

输入范围在-50 和 50 之间,而输出范围在-50² (2500)和 0² (0)之间。大的输入输出值会使训练神经网络变得不稳定,因此,先对数据进行缩放是个好主意。

我们可以使用最小最大缩放器将输入值和输出值分别归一化为 0 到 1 之间的值。

...
# separately scale the input and output variables
scale_x = MinMaxScaler()
x = scale_x.fit_transform(x)
scale_y = MinMaxScaler()
y = scale_y.fit_transform(y)
print(x.min(), x.max(), y.min(), y.max())

我们现在可以定义一个神经网络模型。

经过一些反复试验,我选择了一个模型,它有两个隐藏层,每层有 10 个节点。也许可以尝试其他配置,看看是否可以做得更好。

...
# design the neural network model
model = Sequential()
model.add(Dense(10, input_dim=1, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(10, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(1))

我们将使用均方损失来拟合模型,并使用随机梯度下降的有效 adam 版本来优化模型。

这意味着模型在试图近似映射函数时,将寻求最小化预测值和预期输出值( y )之间的均方误差。

...
# define the loss function and optimization algorithm
model.compile(loss='mse', optimizer='adam')

我们没有很多数据(例如,大约 100 行),因此我们将适合 500 个时代的模型,并使用 10 的小批量。

同样,这些值是经过一点点反复试验后发现的;尝试不同的价值观,看看你是否能做得更好。

...
# ft the model on the training dataset
model.fit(x, y, epochs=500, batch_size=10, verbose=0)

一旦符合,我们就可以评估模型。

我们将对数据集中的每个示例进行预测,并计算误差。完美的近似值是 0.0。这通常是不可能的,因为观测中的噪声、不完整的数据以及未知的底层映射函数的复杂性。

在这种情况下,这是可能的,因为我们有所有的观测值,数据中没有噪声,底层函数也不复杂。

首先,我们可以做出预测。

...
# make predictions for the input data
yhat = model.predict(x)

然后,我们必须反转我们执行的缩放。

这是因为错误是以目标变量的原始单位报告的。

...
# inverse transforms
x_plot = scale_x.inverse_transform(x)
y_plot = scale_y.inverse_transform(y)
yhat_plot = scale_y.inverse_transform(yhat)

然后,我们可以用目标变量的原始单位来计算和报告预测误差。

...
# report model error
print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot))

最后,我们可以创建输入到输出的真实映射的散点图,并将其与输入到预测输出的映射进行比较,看看映射函数的近似在空间上是什么样子。

这有助于发展神经网络正在学习的东西背后的直觉。

...
# plot x vs yhat
pyplot.scatter(x_plot,yhat_plot, label='Predicted')
pyplot.title('Input (x) versus Output (y)')
pyplot.xlabel('Input Variable (x)')
pyplot.ylabel('Output Variable (y)')
pyplot.legend()
pyplot.show()

将这些联系在一起,完整的示例如下所示。

# example of fitting a neural net on x vs x²
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from numpy import asarray
from matplotlib import pyplot
# define the dataset
x = asarray([i for i in range(-50,51)])
y = asarray([i**2.0 for i in x])
print(x.min(), x.max(), y.min(), y.max())
# reshape arrays into into rows and cols
x = x.reshape((len(x), 1))
y = y.reshape((len(y), 1))
# separately scale the input and output variables
scale_x = MinMaxScaler()
x = scale_x.fit_transform(x)
scale_y = MinMaxScaler()
y = scale_y.fit_transform(y)
print(x.min(), x.max(), y.min(), y.max())
# design the neural network model
model = Sequential()
model.add(Dense(10, input_dim=1, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(10, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(1))
# define the loss function and optimization algorithm
model.compile(loss='mse', optimizer='adam')
# ft the model on the training dataset
model.fit(x, y, epochs=500, batch_size=10, verbose=0)
# make predictions for the input data
yhat = model.predict(x)
# inverse transforms
x_plot = scale_x.inverse_transform(x)
y_plot = scale_y.inverse_transform(y)
yhat_plot = scale_y.inverse_transform(yhat)
# report model error
print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot))
# plot x vs y
pyplot.scatter(x_plot,y_plot, label='Actual')
# plot x vs yhat
pyplot.scatter(x_plot,yhat_plot, label='Predicted')
pyplot.title('Input (x) versus Output (y)')
pyplot.xlabel('Input Variable (x)')
pyplot.ylabel('Output Variable (y)')
pyplot.legend()
pyplot.show()

运行该示例首先报告输入和输出变量的值范围,然后报告缩放后相同变量的范围。这证实了缩放操作的执行符合我们的预期。

然后在数据集上拟合和评估模型。

:考虑到算法或评估程序的随机性,或数值精确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到均方误差约为 1,300,单位为平方。如果我们计算平方根,这就给出了以原始单位表示的均方根误差(RMSE)。我们可以看到平均误差在 36 个单位左右,这是可以的,但不是很大。

**你得到了什么结果?**你能做得更好吗? 请在下面的评论中告诉我。

-50 50 0.0 2500.0
0.0 1.0 0.0 1.0
MSE: 1300.776

然后创建散点图,比较输入和实际输出,以及输入和预测输出。

这两个数据系列之间的区别在于映射函数近似的误差。我们可以看出近似是合理的;它捕捉到了大致的形状。我们可以看到有错误,尤其是在 0 输入值附近。

这表明还有很大的改进空间,例如使用不同的激活函数或不同的网络架构来更好地近似映射函数。

Scatter Plot of Input vs. Actual and Predicted Values for the Neural Net Approximation

神经网络近似的输入与实际和预测值的散点图

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

教程

文章

摘要

在本教程中,您发现了神经网络作为函数近似算法背后的直觉。

具体来说,您了解到:

  • 在数据上训练神经网络近似于从输入到输出的未知底层映射函数。
  • 一维输入输出数据集为开发函数近似的直观性提供了有用的基础。
  • 如何开发和评估用于函数近似的小型神经网络?

你有什么问题吗? 在下面的评论中提问,我会尽力回答。

多层感知机神经网络速成课程

原文: machinelearningmastery.com/neural-networks-crash-course/

人工神经网络是一个迷人的研究领域,尽管它们在刚开始时可能会令人生畏。

在该领域中,人们使用许多专门术语来描述数据结构(data structure)和算法(algorithm)。

这篇文章是一个速成课程,它将为您介绍在多层感知机人工神经网络领域中使用的术语和过程。阅读这篇文章后您会知道:

  • 神经网络的组成单元,包括神经元(neuron),权重(weight)和激活函数(activation function)。
  • 如何在层中使用构建块来创建网络。
  • 如何从示例数据中训练网络。

让我们开始吧。

Crash Course In Neural Networks

神经网络速成课程 摄影: Joe Stump ,保留一些权利。

速成课程概述

我们将在这篇文章中简短地介绍以下基础内容:

  1. 多层感知机
  2. 神经元,权重和激活
  3. 神经元的网络
  4. 训练网络

我们将从概述多层感知机开始。

1.多层感知机(Multi-Layer Perceptrons)

人工神经网络(artificial neural networks)领域通常被称为 “神经网络” 或 “多层感知机”。多层感知机可能是最有用的神经网络类型。感知机是单个神经元模型,是较大神经网络的前身。

这个领域研究生物大脑的简单模型如何被用于解决困难计算任务,例如我们在机器学习中看到的预测性建模任务。它的目标不是创建大脑的真实模型,而是开发稳健的算法和数据结构,从而对复杂的问题进行建模。

神经网络的力量在于,它可以从训练数据中学习到表征(representation),以及如何将其与想要预测的输出变量(output variable)最好的联系起来。从这个意义上说,神经网络学习的是映射(mapping)。在数学上,它们能够学习任何映射函数,并且已经被证明是一种通用的近似算法。

神经网络的预测能力来自网络的分层或多层结构。数据结构可以挑出(即学会表示)不同比例或分辨率的特征(feature),并将它们组合成更高阶的特征。例如,从线条到线条的集合,再到各种形状。

2.神经元(Neurons)

神经网络的组成单元是人工神经元(artificial neurons)。

这些计算单元接收加权的输入信号,并使用激活函数(activation function)产生输出信号。

Model of a Simple Neuron

简单神经元的模型

神经元权重(weight)

您可能熟悉线性回归,在这种情况下,输入上的权重非常类似于回归方程中使用的系数。

像线性回归一样,每个神经元也有一个偏差(bias),可以认为它是一个总是具有 1.0 值的输入,它也必须加权。

例如,神经元可能有两个输入(inputs),在这种情况下它需要三个权重。每个输入一个,偏差一个。

虽然可以使用更复杂的初始化(initialization)方案,但是权重通常被初始化为小的随机值,例如 0 到 0.3 范围内的值。

与线性回归一样,较大的权重表明复杂性和脆弱性增加。所以我们一般希望网络中的权重较小,正则化(regularization)技术就是用于处理这个问题。

激活(Activation)

加权输入先进行加总,然后通过激活函数,有时称为转化函数(transfer function)。

激活函数就是神经元接收的加权求和的输入与输出的简单映射。它被称为激活函数,因为它控制神经元激活的阈值和输出信号的强度。

历史上,人们曾经使用简单的激活函数,如果求和输入(summed input)高于阈值,例如 0.5,则神经元将输出值 1.0,否则将输出 0.0。

传统上,人们会使用非线性的激活函数。这允许网络以更复杂的方式组合输入,从而使他们可以学习更复杂的函数。非线性函数,如 logistic 函数,也称为 sigmoid 函数,输出 0 到 1 之间的值,具有 s 形分布; 双曲正切函数也称为 tanh,在-1 到+1 范围内输出相同的分布。

最近,整流激活函数(rectified activation function)已被证明可提供更好的结果。

3.神经元网络

神经元被排列成神经元网络。

一行神经元称为层,一个网络可以有多个层。网络中神经元的架构通常称为网络拓扑。

Model of a Simple Network

简单网络的模型

输入或可见层

从数据集获取输入的底层称为可见层,因为它是网络的公开部分。通常,神经网络使用可见层绘制,每个输入值或数据集中的列具有一个神经元。这些不是如上所述的神经元,而是简单地将输入值传递到下一层。

隐藏层

输入层之后的层称为隐藏层,因为它们不直接暴露给输入。最简单的网络结构是在隐藏层中有一个直接输出值的神经元。

鉴于计算能力和高效库的增加,可以构建非常深的神经网络。深度学习可以指神经网络中有许多隐藏层。它们很深,因为它们在历史上训练起来会非常缓慢,但可能需要几秒钟或几分钟才能使用现代技术和硬件进行训练。

输出层

最后的隐藏层称为输出层,它负责输出与问题所需格式相对应的值或值向量。

输出层中激活函数的选择受到您正在建模的问题类型的严格限制。例如:

  • 回归问题可能具有单个输出神经元,并且神经元可能没有激活功能。
  • 二分类问题可能有一个输出神经元,并使用 sigmoid 激活函数输出 0 到 1 之间的值,以表示预测类 1 的值的概率。这可以通过使用阈值转换为清晰的类值 0.5 和小于阈值的捕捉值为 0,否则为 1。
  • 多分类问题可能在输出层中具有多个神经元,每个类一个(例如,着名的虹膜花分类问题中的三个类别的三个神经元)。在这种情况下,softmax 激活函数可用于输出网络预测每个类值的概率。选择具有最高概率的输出可用于产生清晰的类别分类值。

4.训练网络

配置完成后,需要在数据集上训练神经网络。

数据准备

您必须首先准备数据以进行神经网络的训练。

数据必须是数字,例如实数值。如果您有分类数据,例如值为“male”和“female”的性别属性,则可以将其转换为称为单热编码的实值表示。这是为每个类值添加一个新列的位置(在男性和女性的性别情况下为两列),并且每行添加 0 或 1,具体取决于该行的类值。

对于具有多个类的分类问题,可以在输出变量上使用相同的热编码。这将从单个列创建一个二进制向量,该向量很容易直接与网络输出层中神经元的输出进行比较,如上所述,将为每个类输出一个值。

神经网络要求输入以一致的方式缩放。您可以将其重缩放到 0 到 1 之间的范围,称为标准化。另一种流行的技术是将其标准化,使每列的分布均值为零,标准偏差为 1。

缩放也适用于图像像素数据。诸如单词的数据可以被转换为整数,诸如数据集中的单词的流行度等级以及其他编码技术。

随机梯度下降

用于神经网络的经典且仍然优选的训练算法称为随机梯度下降。

这是一行数据作为输入一次暴露给网络的地方。当网络最终产生输出值时,网络处理输入向上激活神经元。这称为网络上的前向传递。它是在训练网络之后使用的传递类型,以便对新数据做出预测。

将网络输出与预期输出进行比较,并计算误差。然后,该错误通过网络传播回来,一次一层,并根据它们对错误的贡献量来更新权重。这个聪明的数学运算称为反向传播算法

对训练数据中的所有示例重复该过程。更新整个训练数据集的网络之一称为迭代。可以训练网络数十,数百或数千个时期。

重量更新

可以从针对每个训练示例计算的误差更新网络中的权重,这称为在线学习。它可能导致网络快速但又混乱的变化。

或者,可以在所有训练示例中保存错误,并且最后可以更新网络。这称为批量学习,通常更稳定。

通常,因为数据集如此之大并且由于计算效率,批量的大小,在更新之前显示网络的示例的数量通常减少到少量,例如数十或数百个示例。

更新权重的数量由称为学习率的配置参数控制。它也称为步长,控制给定错误对网络权重的步骤或更改。通常使用小的重量尺寸,例如 0.1 或 0.01 或更小。

可以使用您可以设置的其他配置项补充更新等式。

  • 动量是一个术语,它包含先前重量更新的属性,以允许权重在相同方向上继续变化,即使计算的误差较少。
  • 学习率衰减用于降低时期上的学习率,以允许网络在开始时对权重进行大的改变,并且在训练时间表中稍后进行较小的微调改变。

预测

一旦神经网络被训练,它就可以用于做出预测。

您可以对测试或验证数据做出预测,以便估计模型对未见数据的技能。您还可以在操作上部署它并使用它来连续做出预测。

您需要从模型中保存网络拓扑和最终权重集。通过向网络提供输入并执行前向传递来做出预测,从而允许它生成可用作预测的输出。

更多资源

关于人工神经网络的主题有数十年的论文和书籍。

如果您是该领域的新手,我建议您阅读以下资源:

摘要

在这篇文章中,您发现了用于机器学习的人工神经网络

阅读本文后,您现在知道:

  • 神经网络如何不是大脑的模型,而是解决复杂机器学习问题的计算模型。
  • 神经网络由具有权重和激活功能的神经元组成。
  • 网络被组织成神经元层,并使用随机梯度下降进行训练。
  • 在训练神经网络模型之前准备数据是个好主意。

你对神经网络或这篇文章有任何疑问吗?在评论中提出您的问题,我会尽力回答。

Keras 深度学习库中基于卷积神经网络的的目标识别

原文: machinelearningmastery.com/object-recognition-convolutional-neural-networks-keras-deep-learning-library/

Keras 是一个用于深度学习的 Python 库,它包含强大的数值库 Theano 和 TensorFlow。

传统神经网络衰落的一个难题是物体识别。这是模型能够识别图像中的对象的地方。

在这篇文章中,您将了解如何开发和评估 Keras 中用于对象识别的深度学习模型。完成本教程后,您将了解:

  • 关于 CIFAR-10 对象识别数据集以及如何在 Keras 中加载和使用它。
  • 如何创建一个简单的卷积神经网络进行对象识别。
  • 如何通过创建更深层次的卷积神经网络来提升表现。

让我们开始吧。

  • 2016 年 10 月更新:更新了 Keras 1.1.0 和 TensorFlow 0.10.0 的示例。
  • 2017 年 3 月更新:更新了 Keras 2.0.2,TensorFlow 1.0.1 和 Theano 0.9.0 的示例。

CIFAR-10 问题描述

由于物体,位置,照明等几乎无限多的排列,因此难以自动识别照片中的物体。这是一个非常难的问题。

这是计算机视觉中一个经过充分研究的问题,最近也是深度学习能力的重要证明。 加拿大高级研究所(CIFAR)开发了针对该问题的标准计算机视觉和深度学习数据集。

CIFAR-10 数据集由 60,000 张照片组成,分为 10 个类别(因此命名为 CIFAR-10)。课程包括飞机,汽车,鸟类,猫等常见物品。数据集以标准方式分割,其中 50,000 个图像用于训练模型,剩余的 10,000 个用于评估其表现。

这些照片的颜色为红色,绿色和蓝色,但很小,尺寸为 32 x 32 像素。

使用非常大的卷积神经网络实现了现有技术的结果。您可以在 Rodrigo Benenson 的网页上了解 CIFAR-10 的结果状态。模型表现以分类准确度报告,非常好的表现超过 90%,人类在该问题上的表现为 94%,而在撰写本文时,最先进的结果为 96%。

有一个 Kaggle 比赛使用了 CIFAR-10 数据集。这是一个加入讨论开发问题的新模型,并以模型和脚本为起点的好地方。

在 Keras 中加载 CIFAR-10 数据集

CIFAR-10 数据集可以轻松加载到 Keras 中。

Keras 可以自动下载 CIFAR-10 等标准数据集,并使用 cifar10.load_data()函数将它们存储在〜/ .keras / datasets 目录中。此数据集很大,为 163 兆字节,因此下载可能需要几分钟。

下载后,对该函数的后续调用将加载准备好使用的数据集。

数据集存储为酸洗训练和测试集,准备在 Keras 中使用。每个图像表示为三维矩阵,具有红色,绿色,蓝色,宽度和高度的尺寸。我们可以使用 matplotlib 直接绘制图像。

# Plot ad hoc CIFAR10 instances
from keras.datasets import cifar10
from matplotlib import pyplot
from scipy.misc import toimage
# load data
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
# create a grid of 3x3 images
for i in range(0, 9):
	pyplot.subplot(330 + 1 + i)
	pyplot.imshow(toimage(X_train[i]))
# show the plot
pyplot.show()

运行代码可创建 3×3 的照片。图像已经从 32×32 的小尺寸放大,但你可以清楚地看到卡车马和汽车。您还可以在一些强制为方形宽高比的图像中看到一些失真。

Small Sample of CIFAR-10 Images

CIFAR-10 图像的小样本

CIFAR-10 的简单卷积神经网络

使用卷积神经网络(CNN)可以最好地解决 CIFAR-10 问题。

我们可以通过定义本例中需要的所有类和函数来快速入门。

# Simple CNN model for CIFAR-10
import numpy
from keras.datasets import cifar10
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.constraints import maxnorm
from keras.optimizers import SGD
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from keras import backend as K
K.set_image_dim_ordering('th')

好的做法是,我们接下来用常数初始化随机数种子,以确保结果可重复。

# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

接下来,我们可以加载 CIFAR-10 数据集。

# load data
(X_train, y_train), (X_test, y_test) = cifar10.load_data()

对于红色,绿色和蓝色通道中的每一个,像素值在 0 到 255 的范围内。

使用标准化数据是一种很好的做法。因为输入值很好理解,所以我们可以通过将每个值除以最大值 255 来轻松归一化到 0 到 1 的范围。

注意,数据作为整数加载,因此我们必须将其转换为浮点值才能执行除法。

# normalize inputs from 0-255 to 0.0-1.0
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train = X_train / 255.0
X_test = X_test / 255.0

输出变量定义为每个类从 0 到 1 的整数向量。

我们可以使用单热编码将它们转换为二进制矩阵,以便最好地对分类问题进行建模。我们知道这个问题有 10 个类,所以我们可以期望二进制矩阵的宽度为 10。

# one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]

让我们首先将一个简单的 CNN 结构定义为基线,并评估它对问题的执行情况。

我们将使用具有两个卷积层的结构,然后进行最大池化并将网络展平为完全连接的层以做出预测。

我们的基线网络结构可归纳如下:

  1. 卷积输入层,32 个大小为 3×3 的特征映射,整流器激活函数和最大范数的权重约束设置为 3。
  2. dropout 率设定为 20%。
  3. 卷积层,32 个特征映射,大小为 3×3,整流器激活函数和最大范数的权重约束设置为 3。
  4. Max Pool 层,大小为 2×2。
  5. 展平层。
  6. 完全连接的层具有 512 个单元和整流器激活功能。
  7. dropout 率设定为 50%。
  8. 完全连接的输出层,10 个单元和 softmax 激活功能。

对数损失函数与随机梯度下降优化算法一起使用,该算法配置有大动量和重量衰减开始,学习率为 0.01。

# Create the model
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(3, 32, 32), padding='same', activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Conv2D(32, (3, 3), activation='relu', padding='same', kernel_constraint=maxnorm(3)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
epochs = 25
lrate = 0.01
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
print(model.summary())

我们可以将这个模型与 25 个时期和 32 个批量大小相匹配。

选择了少量的时代来帮助保持本教程的发展。通常,对于该问题,时期的数量将是一个或两个数量级。

一旦模型适合,我们在测试数据集上对其进行评估并打印出分类准确度。

# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=32)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))

运行此示例提供以下结果。首先总结网络结构,确认我们的设计是正确实现的。

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 32, 32, 32)        896       
_________________________________________________________________
dropout_1 (Dropout)          (None, 32, 32, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 32, 32, 32)        9248      
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 32, 16, 16)        0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 8192)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               4194816   
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 10)                5130      
=================================================================
Total params: 4,210,090.0
Trainable params: 4,210,090.0
Non-trainable params: 0.0
_________________________________________________________________

在训练和测试数据集的每个时期打印分类准确度和损失。该模型在测试装置上进行评估,达到 70.85%的准确度,这并不是很好。

...
Epoch 20/25
50000/50000 [==============================] - 143s - loss: 0.2858 - acc: 0.9011 - val_loss: 1.0091 - val_acc: 0.7063
Epoch 21/25
50000/50000 [==============================] - 143s - loss: 0.2693 - acc: 0.9067 - val_loss: 1.0122 - val_acc: 0.7069
Epoch 22/25
50000/50000 [==============================] - 143s - loss: 0.2544 - acc: 0.9119 - val_loss: 1.0240 - val_acc: 0.7097
Epoch 23/25
50000/50000 [==============================] - 143s - loss: 0.2399 - acc: 0.9168 - val_loss: 1.0680 - val_acc: 0.7077
Epoch 24/25
50000/50000 [==============================] - 143s - loss: 0.2285 - acc: 0.9197 - val_loss: 1.0702 - val_acc: 0.7119
Epoch 25/25
50000/50000 [==============================] - 143s - loss: 0.2177 - acc: 0.9238 - val_loss: 1.0686 - val_acc: 0.7085
Accuracy: 70.85%

我们可以通过创建更深入的网络来显着提高准确率。这是我们将在下一节中看到的内容。

用于 CIFAR-10 的更大卷积神经网络

我们已经看到一个简单的 CNN 在这个复杂的问题上表现不佳。在本节中,我们将着眼于扩大模型的大小和复杂性。

让我们设计上面简单 CNN 的深层版本。我们可以引入额外的一轮卷积以及更多的特征映射。我们将使用相同的 Convolutional,Dropout,Convolutional 和 Max Pooling 层模式。

使用 32,64 和 128 个要素贴图将重复此模式 3 次。效果是在给定最大池层的情况下,越来越多的特征图具有越来越小的尺寸。最后,将在网络的输出端使用额外的更大的 Dense 层,以尝试更好地将大量要素图转换为类值。

我们可以总结一个新的网络架构如下:

  • 卷积输入层,32 个大小为 3×3 的特征映射和整流器激活功能。
  • dropout 层为 20%。
  • 卷积层,32 个特征映射,大小为 3×3,具有整流器激活功能。
  • Max Pool 层,大小为 2×2。
  • 卷积层,64 个特征映射,大小为 3×3,具有整流器激活功能。
  • dropout 层为 20%。
  • 卷积层,64 个特征映射,大小为 3×3,具有整流器激活功能。
  • Max Pool 层,大小为 2×2。
  • 卷积层,128 个特征图,大小为 3×3,具有整流器激活功能。
  • dropout 层为 20%。
  • 卷积层,128 个特征图,大小为 3×3,具有整流器激活功能。
  • Max Pool 层,大小为 2×2。
  • 展平层。
  • dropout 层为 20%。
  • 完全连接的层具有 1024 个单元和整流器激活功能。
  • dropout 层为 20%。
  • 完全连接的层具有 512 个单元和整流器激活功能。
  • dropout 层为 20%。
  • 完全连接的输出层,10 个单元和 softmax 激活功能。

我们可以很容易地在 Keras 中定义这种网络拓扑,如下所示:

# Create the model
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(3, 32, 32), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(Conv2D(32, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(Conv2D(64, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(Dropout(0.2))
model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dropout(0.2))
model.add(Dense(1024, activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu', kernel_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
epochs = 25
lrate = 0.01
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
print(model.summary())

我们可以使用与上述相同的程序和相同数量的时期来拟合和评估该模型,但是通过一些小的实验发现更大的批量大小为 64。

numpy.random.seed(seed)
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=epochs, batch_size=64)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))

运行此示例将在每个时期打印训练和测试数据集的分类准确率和损失。最终模型的分类精度估计值为 80.18%,比我们的简单模型好近 10 个点。

# 50000/50000 [==============================] - 34s - loss: 0.4993 - acc: 0.8230 - val_loss: 0.5994 - val_acc: 0.7932
# Epoch 20/25
# 50000/50000 [==============================] - 34s - loss: 0.4877 - acc: 0.8271 - val_loss: 0.5986 - val_acc: 0.7932
# Epoch 21/25
# 50000/50000 [==============================] - 34s - loss: 0.4714 - acc: 0.8327 - val_loss: 0.5916 - val_acc: 0.7959
# Epoch 22/25
# 50000/50000 [==============================] - 34s - loss: 0.4603 - acc: 0.8376 - val_loss: 0.5954 - val_acc: 0.8003
# Epoch 23/25
# 50000/50000 [==============================] - 34s - loss: 0.4454 - acc: 0.8410 - val_loss: 0.5742 - val_acc: 0.8024
# Epoch 24/25
# 50000/50000 [==============================] - 34s - loss: 0.4332 - acc: 0.8468 - val_loss: 0.5829 - val_acc: 0.8027
# Epoch 25/25
# 50000/50000 [==============================] - 34s - loss: 0.4217 - acc: 0.8498 - val_loss: 0.5785 - val_acc: 0.8018
# Accuracy: 80.18%

扩展以提高模型表现

我们在这个非常困难的问题上取得了很好的成绩,但我们仍然是实现世界级成果的好方法。

以下是您可以尝试扩展模型并提高模型表现的一些想法。

  • 训练更多时代。每个模型都训练了极少数的时代,25。通常训练大型卷积神经网络数百或数千个时代。我希望通过大幅提高训练时期的数量来实现绩效提升。
  • 图像数据增强。图像中的对象位置不同。通过使用一些数据增强可以实现模型表现的另一个提升。诸如标准化和随机移位以及水平图像翻转的方法可能是有益的。
  • 更深入的网络拓扑。呈现的较大网络很深,但可以针对该问题设计更大的网络。这可能涉及更接近输入的更多特征图,并且可能涉及较不积极的池。另外,可以采用并评估已经显示有用的标准卷积网络拓扑结构。

摘要

在这篇文章中,您发现了如何在 Keras 中创建深度学习模型,以便在照片中进行对象识别。

完成本教程后,您了解到:

  • 关于 CIFAR-10 数据集以及如何在 Keras 中加载它并从数据集中绘制特殊示例。
  • 如何训练和评估一个简单的卷积神经网络的问题。
  • 如何将简单的卷积神经网络扩展为深度卷积神经网络,以提高对难题的表现。
  • 如何使用数据扩充来进一步推动困难的对象识别问题。

您对对象识别或此帖有任何疑问吗?在评论中提出您的问题,我会尽力回答。

流行的深度学习库

原文: machinelearningmastery.com/popular-deep-learning-libraries/

有很多深度学习库可供选择。

哪些是值得学习的优秀专业库,哪些是侧面项目,应该避免。很难分辨出来。

在这篇文章中,您将发现您应该考虑在自己的深度学习项目中学习和使用的顶级深度学习库。

让我们开始吧。

Popular Deep Learning Libraries

流行的深度学习库 照片由 Nikki 拍摄,保留一些权利。

概观

在这篇文章中,您将发现以下深度学习库。所有这些都是使用各种不同的许可许可证的开源。

  • Theano
  • 火炬
  • 咖啡
  • DeepLearning4J

还有许多其他优秀的库和平台。一些更值得尊敬的提及包括 Google 的 TensorFlow ,R 中的 darch ,JavaScript 中的 Convnet.js (用于学习), Mocha 在 Julia , CNTK 由微软和 H2O Web API。

Theano

Theano 是由 LISA 集团(现为 MILA )开发的 Python 框架,由蒙特利尔大学的 Yoshua Bengio 运营,用于研究和开发最先进的深度学习算法。

它更好地描述为一个数学表达式编译器,您可以在其中象征性地定义您想要的内容,并且框架使您的程序符合您在 GPU 或 CPU 上高效运行的程序。

它不仅仅是一个深度学习库,也是一个研究平台。你必须自己做很多工作来创建你想要的模型。例如,没有神经网络类。

然而,有一个优秀的深度学习教程,向您展示如何为深度学习创建类和函数。例如,它提供了创建以下深度学习算法的分步示例:

在线查看整个教程或下载 PDF 版

Theano 实际上是一个生态系统,在实践中你不会直接使用 Theano。在 Theano 之上构建了一个长的库列表,提供了方便的包装 API。一些更受欢迎的项目包括:

这些项目本身就变成了非常大的项目,为底层的 Theano 平台提供了有用的 API,大大加快了将模型组合在一起的速度。

如果您是 Python 开发人员并且对更广泛的深度学习或研究感兴趣,那么这就是您的平台。

资源

火炬

Torch(使用奇数版本编号称为 Torch7)是由 Ronan CollobertClement FarabetKoray Kavukcuoglu 开发的 Lua 深度学习框架,用于深入研究和开发学习算法。它由纽约大学的 CILVR 实验室Yann LeCun 的家)使用和推广。

使用 Torch 并由 Facebook AI 实验室,Google DeepMind,Twitter 和其他许多人进一步开发。

在幕后,Torch 使用 C / C ++库以及 GPU 的 CUDA。它的目标是加速使用 C 友好语言 Lua 来提供一个不那么令人生畏的界面。

Torch 的目标是在构建科学算法的过程中获得最大的灵活性和速度,同时使过程变得非常简单

有很多文档,但它是一团糟。 Torch 的流行应用是用于卷积神经网络的监督图像问题,以及具有深度强化学习的更复杂领域的代理。

如果您主要对强化学习感兴趣,Torch 可能是您的平台。

资源

咖啡

Caffe 是由 Yangqing Jia 在伯克利远景和学习中心开发的用于监督计算机视觉问题的 Python 深度学习库。

主要关注的是卷积神经网络,它可能是世界领先者。

该库的一大好处是可以从 Caffe Model Zoo 下载并立即使用的预训练网络数量。这包括可以在标准计算机视觉数据集上实现世界级结果的最先进模型。

例如,这里有一些世界级模型的教程:

如果您主要对卷积神经网络和图像问题感兴趣,那么 Caffe 可能就是您的平台。

资源

DeepLearning4J

DeepLearning4J(简称 DL4J)是由 Adam Gibson 用于商业深度学习项目的 Java(和 JVM 语言)开发的深度学习框架。

DL4J 是一个基于 JVM,以行业为中心,商业支持的分布式深度学习框架,旨在解决在合理时间内涉及大量数据的问题

DeepLearning4J 是一个灵活的平台,它提供了一套最先进的深度学习算法,不仅限于:

  • 深信仰网络
  • 堆叠去噪自编码器
  • 卷积神经网络
  • 长短期记忆单位
  • 递归神经网络

文档非常好,涵盖了一系列主题,包括算法本身的一些理论和代码示例。

它具有与整个 Java 生态系统一起使用的优势,这是商业软件开发中的主要平台,包括 JVM 上的其他语言(例如 Scala)和大数据平台(Hadoop 和 Spark)。

资源

深度学习工具综述

很多人已经完成了深度学习库和工具的总结。本节列出了一些可用于深入学习深度学习工具的总结和其他资源。

摘要

在这篇文章中,您将发现最受欢迎的深度学习工具和库。

具体来说,您了解到:

  • Theano
  • 火炬
  • 咖啡
  • DeepLearning4J

您是否使用过一种或多种这些工具?请在评论中告诉我您对它们的看法。

您对本文中列出的深度学习或库有任何疑问吗?在评论中提出您的问题,我会尽力回答。

面向程序员的实用深度学习(复习)

原文:machinelearningmastery.com/practical-d…

最后更新于 2019 年 11 月 1 日

实用的深度学习是一门具有挑战性的学科。

它通常以自下而上的方式教授,要求您在最终学习神经网络技术之前首先熟悉线性代数、微积分和数学优化。这可能需要几年的时间,而且大部分的背景理论都不会帮你得到好的结果,快。

相反,可以使用自上而下的方法,首先学习如何利用现实问题的深度学习模型获得结果,然后进一步学习这些方法是如何工作的。

这正是在 fast.ai 上教授的流行事业中使用的方法,名为“程序员实用深度学习”

在这篇文章中,您将发现 fast.ai 课程,该课程面向希望入门并擅长深度学习的开发人员,包括课程本身的概述、课程中介绍的最佳实践以及对整个课程的讨论和回顾。

用我的新书用 Python 深度学习来启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

我们开始吧。

  • 2019 年 11 月更新:修复了 2019 版课程更新后的断链。

Practical Deep Learning for Coders Review

程序员实用深度学习回顾 图片由弗雷泽·穆梅利提供,版权所有。

概观

本教程分为四个部分;它们是:

  1. 课程概述
  2. 课程分解
  3. 最佳实践
  4. 讨论和回顾

课程概述

fast.ai 是一个小型组织,提供关于实用机器学习和深度学习的免费培训。

他们的使命是让深度学习对所有人开放,真正对开发者开放。

在写这篇文章的时候,fast.ai 提供了四门课程;它们是:

该组织由杰瑞米·霍华德(恩利蒂克、卡格尔等)和蕾切尔·托马斯(优步三藩市大学等)创立。

杰里米是一名世界级的从业者,他首先在卡格尔上取得了优异的表现,后来加入了公司。他对机器学习或深度学习的实践有什么要说的都应该考虑。雷切尔拥有合作伙伴关系所需的学术(博士)和数学才能,并继续提供深度学习的一些相关数学基础的姐妹课程。

大多数课程首先由杰里米或雷切尔在旧金山大学讲授,然后视频和课程材料免费提供。

值得注意的是他们的第一个也是最重要的课程:

  • 面向程序员的实用深度学习(第一部分)

该课程于 2016 年底首次推出。最近对其进行了更新或重新创建(2017 年底),这是编写本报告时可用的课程的当前版本。这可能会随着未来的更新而改变。

重要的是,课程从 v1 到 v2 的主要变化是从 Keras 深度学习框架(谷歌 TensorFlow 的包装器)转移到自己的开源 fast.ai 库,它为脸书的 PyTorch 深度学习框架提供了包装器。

这种从 Keras 到 PyTorch 的转变是出于灵活性的考虑。他们自己的包装器捕获了许多最先进的方法和最佳实践,但也隐藏了许多细节。它可能最适合从业者,而不太适合学者,比更一般的 Keras。

课程分解

更新:我复习了 2018 版的课程,虽然 2019 版现在有了。

本课程的完整讲座列表如下(每个嵌入式视频的链接)。

  • 1.识别猫和狗。
  • 2.改进您的图像分类器。
  • 3.理解回旋。
  • 4.结构化、时间序列和语言模型。
  • 5.协同过滤。在训练循环中。
  • 6.解释嵌入。从零开始的 RNNs。
  • 7.从头再来。

我更喜欢以双倍的速度看视频和做笔记。所有视频都可以作为 YouTube 播放列表。

Example of Embedding Lecture with Course Materials

将讲座嵌入课程材料的示例

该课程采用自上而下的教学方法,而不是自下而上的方法。具体来说,这意味着首先展示如何做某事,然后重复这个过程,但展示所有的细节。这并不意味着后续一定要数学和理论;相反,它指的是如何取得结果的实际问题。

这是处理材料的一个很好的方法。第三讲中的一张幻灯片(在整个课程中多次出现)概述了这种深度学习的方法;具体来说,前几个教程演示了如何使用计算机视觉、结构化数据(表格数据)、自然语言处理和协作过滤来实现结果,然后这些主题又以相反的顺序进行了介绍,但是模型是从头开始开发的,以展示它们是如何工作的(即不是为什么工作)。

Overview of Course Structure

课程结构概述

最佳实践

课程的重点是教授最佳实践。

这些是使用深度学习方法处理特定预测建模问题的推荐方法。

最佳实践以过程(例如,处理新的预测建模问题的一致方式)和技术的形式呈现。它们也被烘焙成所有讲座中使用的名为 fast.ai 的 PyTorch 包装。

涵盖了许多最佳实践,有些是微妙的,因为它是介绍主题的方式,而不是指出实践是传统方法的替代方法。

有人试图将最佳做法分类;例如:

查看我的笔记,我总结了以下一些最佳实践:

  • 在计算机视觉中始终使用迁移学习(例如 ImageNet 模型)作为起点,但要仔细选择模型中的点来添加新的图层。
  • 在计算机视觉的迁移学习(如差异学习)中,尝试不同层次的不同学习速率。
  • 使用测试时间增加给一个模型多次机会做出一个好的预测(哇!).
  • 首先用非常小的图像训练模型,然后用更大的图像重新训练(例如,调整图像的大小)。
  • 使用循环学习率来快速为 SGD 找到一个好的学习率(例如学习率查找器)。
  • 使用余弦退火学习速率计划,在训练期间重新开始。
  • 将迁移学习用于语言模型。
  • 更广泛地使用嵌入层,例如用于所有分类输入变量,而不仅仅是单词。
  • 在协同过滤中为电影和用户使用嵌入层。

我遇到了每一种方法,我只是没有考虑到它们应该是起点(例如最佳实践)。相反,我认为它们是在项目需要时提升绩效的工具。

Easy Steps to Train a World-Class Image Classifier

训练世界级图像分类器的简单步骤

讨论和回顾

课程很棒。

  • 杰里米是一个大师级的实践者和优秀的沟通者。
  • 细节层次是对的:先高层,再低层,但都是怎么做,不是为什么。
  • 注重应用而不是技术。

如果你是一个深度学习的实践者或者你想成为,那么这门课程是必须的。

视频对我来说太长了。当我在文本编辑器中做笔记时,我使用了 YouTube 播放列表并双倍时间观看视频。

我在这个阶段对使用 fast.ai 库或 pytorch 不感兴趣,所以我浏览或跳过了代码特定的部分。总的来说,我不喜欢从视频中学习代码,所以我会跳过这些部分。

这些讲座的价值在于看到杰里米使用深度学习方法通过预测建模问题的具体方式背后的步骤和思维过程。因为他专注于好的和快速的结果,你得到的正是你需要知道的,没有其他人强迫你在进入重点之前涉水而过的细节和背景。

有点像吴恩达,他把一切解释得如此简单,以至于你有足够的信心拿起工具并开始使用它们。

他在卡格尔竞赛中的能力让你想深入过去的竞赛数据集来立即测试这些方法。

最后,他在论坛上培养的社区意识,以及他在博客上发布的总结他的教导的帖子,让你想加入并做出贡献。

同样,如果你真的想成为一个深度学习的实践者,这是需要观察的。

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

摘要

在这篇文章中,您发现了 fast.ai 课程,该课程面向希望开始并擅长深度学习的开发人员

你学过这门课或者学过这些材料吗? 在下面的评论中让我知道你对它的想法。

你有什么问题吗? 在下面的评论中提问,我会尽力回答。

使用深度学习预测电影评论的情感

原文: machinelearningmastery.com/predict-sentiment-movie-reviews-using-deep-learning/

情感分析是一种自然语言处理问题,其中理解文本并预测潜在意图。

在这篇文章中,您将了解如何使用 Keras 深度学习库在 Python 中预测电影评论的积极或消极情感。

阅读这篇文章后你会知道:

  • 关于自然语言处理的 IMDB 情感分析问题以及如何在 Keras 中加载它。
  • 如何在 Keras 中使用单词嵌入来解决自然语言问题。
  • 如何开发和评估 IMDB 问题的多层感知机模型。
  • 如何为 IMDB 问题开发一维卷积神经网络模型。

让我们开始吧。

  • 2016 年 10 月更新:更新了 Keras 1.1.0 和 TensorFlow 0.10.0 的示例。
  • 2017 年 3 月更新:更新了 Keras 2.0.2,TensorFlow 1.0.1 和 Theano 0.9.0 的示例。

Predict Sentiment From Movie Reviews Using Deep Learning

使用深度学习预测电影评论的情感 SparkCBC 的照片,保留一些权利。

IMDB 电影评论情感问题描述

数据集是大型电影评论数据集,通常称为 IMDB 数据集。

大型电影评论数据集(通常称为 IMDB 数据集)包含 25,000 个用于训练的高极移动评论(好的或坏的)以及用于测试的相同数量。问题是确定给定的移动评论是否具有正面或负面情感。

这些数据由斯坦福大学的研究人员收集并用于 2011 年论文 [PDF],其中 50/50 的数据用于训练和测试。准确度达到 88.89%。

该数据还被用作 2014 年底至 2015 年初名为“袋子爆米花袋”的 Kaggle 比赛的基础。获胜者达到 99%时,准确率达到 97%以上。

使用 Keras 加载 IMDB 数据集

Keras 可以访问内置的 IMDB 数据集。

keras.datasets.imdb.load_data()允许您以可用于神经网络和深度学习模型的格式加载数据集。

单词已被整数替换,表示数据集中单词的绝对流行度。因此,每个评论中的句子由一系列整数组成。

第一次调用 imdb.load_data()会将 IMDB 数据集下载到您的计算机并将其作为 32 兆字节文件存储在〜/ .keras / datasets / imdb.pkl 下的主目录中。

有用的是,imdb.load_data()提供了额外的参数,包括要加载的顶部字的数量(其中具有较低整数的字在返回的数据中标记为零),要跳过的顶部字的数量(以避免“该”的)以及支持的最大评论期限。

让我们加载数据集并计算它的一些属性。我们将首先加载一些库并将整个 IMDB 数据集作为训练数据集加载。

import numpy
from keras.datasets import imdb
from matplotlib import pyplot
# load the dataset
(X_train, y_train), (X_test, y_test) = imdb.load_data()
X = numpy.concatenate((X_train, X_test), axis=0)
y = numpy.concatenate((y_train, y_test), axis=0)

接下来,我们可以显示训练数据集的形状。

# summarize size
print("Training data: ")
print(X.shape)
print(y.shape)

运行此代码段,我们可以看到有 50,000 条记录。

Training data:
(50000,)
(50000,)

我们还可以打印唯一的类值。

# Summarize number of classes
print("Classes: ")
print(numpy.unique(y))

我们可以看到,这是一个二分类问题,在评论中有好的和坏的情感。

Classes:
[0 1]

接下来,我们可以了解数据集中唯一单词的总数。

# Summarize number of words
print("Number of words: ")
print(len(numpy.unique(numpy.hstack(X))))

有趣的是,我们可以看到整个数据集中只有不到 100,000 个单词。

Number of words:
88585

最后,我们可以了解平均审核长度。

# Summarize review length
print("Review length: ")
result = [len(x) for x in X]
print("Mean %.2f words (%f)" % (numpy.mean(result), numpy.std(result)))
# plot review length
pyplot.boxplot(result)
pyplot.show()

我们可以看到,平均评论不到 300 字,标准差超过 200 字。

Review length:
Mean 234.76 words (172.911495)

我们可以看到一个指数分布的盒子和胡须图,我们可以看到一个指数分布,我们可以覆盖分布的质量,剪切长度为 400 到 500 字。

Review Length in Words for IMDB Dataset

查看 IMDB 数据集的单词长度

Word 嵌入

自然语言处理领域的最新突破称为字嵌入

这是一种在高维空间中将单词编码为实值向量的技术,其中单词之间的意义相似性转换为向量空间中的接近度。

离散词被映射到连续数的向量。当使用神经网络处理自然语言问题时这很有用,深度学习模型我们需要数字作为输入。

Keras 提供了一种方便的方法,可以将单词的正整数表示转换为嵌入层的单词嵌入。

该层采用定义映射的参数,包括也称为词汇量大小的预期词的最大数量(例如,将被视为整数的最大整数值)。该层还允许您为每个单词向量指定维度,称为输出维度。

我们想为 IMDB 数据集使用单词嵌入表示。

假设我们只对数据集中前 5,000 个最常用的单词感兴趣。因此我们的词汇量将为 5,000。我们可以选择使用 32 维向量来表示每个单词。最后,我们可以选择将最大审核长度限制为 500 字,将评论截断时间缩短,并将填充评论缩短为 0 值。

我们将加载 IMDB 数据集,如下所示:

imdb.load_data(nb_words=5000)

然后,我们将使用 Keras 实用程序使用 sequence.pad_sequences()函数将数据集截断或填充到每个观察的长度 500。

X_train = sequence.pad_sequences(X_train, maxlen=500)
X_test = sequence.pad_sequences(X_test, maxlen=500)

最后,稍后,我们模型的第一层将是使用 Embedding 类创建的单词嵌入层,如下所示:

Embedding(5000, 32, input_length=500)

对于给定的复习训练或整数格式的测试模式,该第一层的输出将是大小为 32×500 的矩阵。

既然我们知道如何在 Keras 中加载 IMDB 数据集以及如何为它使用单词嵌入表示,那么让我们开发并评估一些模型。

用于 IMDB 数据集的简单多层感知机模型

我们可以从开发一个具有单个隐藏层的简单多层感知机模型开始。

嵌入表示这个词是一个真正的创新,我们将通过一个相对简单的神经网络展示 2011 年被认为是世界级的结果。

让我们首先导入此模型所需的类和函数,并将随机数生成器初始化为常量值,以确保我们可以轻松地重现结果。

# MLP for the IMDB problem
import numpy
from keras.datasets import imdb
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

接下来,我们将加载 IMDB 数据集。我们将简化数据集,正如单词嵌入一节中所讨论的那样。只会加载前 5,000 个单词。

我们还将使用 50%/ 50%的数据集拆分进行训练和测试。这是一种很好的标准拆分方法。

# load the dataset but only keep the top n words, zero the rest
top_words = 5000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)

我们将以 500 字的方式绑定评论,截断更长的评论和零填充更短的评论。

max_words = 500
X_train = sequence.pad_sequences(X_train, maxlen=max_words)
X_test = sequence.pad_sequences(X_test, maxlen=max_words)

现在我们可以创建我们的模型。我们将使用嵌入层作为输入层,将词汇表设置为 5,000,将字向量大小设置为 32 维,将 input_length 设置为 500.第一层的输出将是 32×500 大小的矩阵,如上一节所述。

我们将嵌入层输出展平为一维,然后使用一个 250 单位的密集隐藏层和整流器激活功能。输出层有一个神经元,并将使用 sigmoid 激活输出 0 和 1 的值作为预测。

该模型使用对数损失,并使用有效的 ADAM 优化程序进行优化。

# create the model
model = Sequential()
model.add(Embedding(top_words, 32, input_length=max_words))
model.add(Flatten())
model.add(Dense(250, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())

我们可以适应模型并在训练时使用测试集作为验证。这个模型很快就会过度使用,因此我们将使用很少的训练时期,在这种情况下只需 2 个。

有很多数据,所以我们将使用 128 的批量大小。在训练模型后,我们评估其在测试数据集上的准确率。

# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=2, batch_size=128, verbose=2)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))

运行此示例适合模型并总结估计的表现。我们可以看到,这个非常简单的模型获得了近 86.94%的分数,这是在原始论文的附近,只需很少的努力。

Train on 25000 samples, validate on 25000 samples
Epoch 1/2
39s - loss: 0.5160 - acc: 0.7040 - val_loss: 0.2982 - val_acc: 0.8716
Epoch 2/2
37s - loss: 0.1897 - acc: 0.9266 - val_loss: 0.3143 - val_acc: 0.8694
Accuracy: 86.94%

我确信如果我们训练这个网络,我们可以做得更好,也许使用更大的嵌入并添加更多的隐藏层。让我们尝试不同的网络类型。

IMDB 数据集的一维卷积神经网络模型

设计卷积神经网络以尊重图像数据中的空间结构,同时对场景中学习对象的位置和方向具有鲁棒性。

该相同原理可用于序列,例如电影评论中的一维单词序列。使 CNN 模型对于学习识别图像中的对象具有吸引力的相同属性可以帮助学习单词段落中的结构,即对于特征的特定位置的技术不变性。

Keras 分别支持 Conv1D 和 MaxPooling1D 类的一维卷积和池化。

再次,让我们导入此示例所需的类和函数,并将随机数生成器初始化为常量值,以便我们可以轻松地重现结果。

# CNN for the IMDB problem
import numpy
from keras.datasets import imdb
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import MaxPooling1D
from keras.layers.embeddings import Embedding
from keras.preprocessing import sequence
# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)

我们也可以像以前一样加载和准备我们的 IMDB 数据集。

# load the dataset but only keep the top n words, zero the rest
top_words = 5000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words=top_words)
# pad dataset to a maximum review length in words
max_words = 500
X_train = sequence.pad_sequences(X_train, maxlen=max_words)
X_test = sequence.pad_sequences(X_test, maxlen=max_words)

我们现在可以定义我们的卷积神经网络模型。这次,在嵌入输入层之后,我们插入一个 Conv1D 层。该卷积层具有 32 个特征映射,并且一次读取嵌入的单词表示 3 个向量元素的嵌入单词嵌入。

卷积层之后是 1D max pooling layer,其长度和步幅为 2,使卷积层的特征映射的大小减半。网络的其余部分与上面的神经网络相同。

# create the model
model = Sequential()
model.add(Embedding(top_words, 32, input_length=max_words))
model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(250, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())

我们也像以前一样适应网络。

# Fit the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=2, batch_size=128, verbose=2)
# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)
print("Accuracy: %.2f%%" % (scores[1]*100))

运行该示例,我们首先会看到网络结构的摘要。我们可以看到我们的卷积层保留了 32 维输入的嵌入输入层的维度,最多 500 个字。池化层通过将其减半来压缩该表示。

运行该示例对上述神经网络模型提供了一个小但令人欢迎的改进,准确率接近 87.79%。

Train on 25000 samples, validate on 25000 samples
Epoch 1/2
38s - loss: 0.4451 - acc: 0.7640 - val_loss: 0.3107 - val_acc: 0.8660
Epoch 2/2
39s - loss: 0.2373 - acc: 0.9064 - val_loss: 0.2909 - val_acc: 0.8779
Accuracy: 87.79%

同样,存在很多进一步优化的机会,例如使用更深和/或更大的卷积层。一个有趣的想法是将最大池化层设置为使用 500 的输入长度。这会将每个要素图压缩为单个 32 长度向量,并可以提高表现。

摘要

在这篇文章中,您发现了用于自然语言处理的 IMDB 情感分析数据集。

您学习了如何为情感分析开发深度学习模型,包括:

  • 如何加载和查看 Keras 中的 IMDB 数据集。
  • 如何开发一个用于情感分析的大型神经网络模型。
  • 如何开发一种用于情感分析的一维卷积神经网络模型。

您对情感分析或此帖有任何疑问吗?在评论中提出您的问题,我会尽力回答。