目录

Python深度学习第三讲神经网络

《Python深度学习》第三讲:神经网络

在前面的课程里,我们已经了解了深度学习的数学基础,也用一个简单的例子展示了神经网络的强大能力。本讲我们要更深入地探讨神经网络的结构、训练过程,以及如何用它解决实际问题。


3.1 神经网络剖析

先来聊聊神经网络的核心组件:层(Layer)。

想象一下,你有一堆积木,你可以用这些积木搭建出各种各样的东西。在神经网络里,层就像是这些积木,你可以用它们搭建出复杂的模型。每一层都有自己的功能,比如,有些层可以处理图像数据,有些层可以处理时间序列数据。这些层组合在一起,就形成了一个强大的神经网络。

我们来看看最常见的几种层。

  • Dense层 :这是最简单的层,它处理的是向量数据。比如,你有一组数字,Dense层可以对这些数字进行变换,提取出更有用的信息。
  • Conv2D层 :这个层专门用来处理图像数据。它可以在图像中找到局部的模式,比如边缘、纹理等。这对于图像分类任务特别有用。
  • LSTM层 :这个层用来处理时间序列数据,比如股票价格、天气数据等。它可以记住过去的信息,对未来做出预测。

神经网络的结构就像是一个数据处理的流水线。

数据从输入层进入,经过一层层的处理,最后从输出层出来。每一层都在对数据进行某种变换,让数据越来越接近我们想要的结果。比如,对于图像分类任务,输入层接收图像数据,中间的层提取图像的特征,最后的输出层告诉我们图像属于哪个类别。


3.2 Keras简介

接下来,我们来看看Keras这个强大的工具。

Keras是一个非常友好的深度学习框架,它就像是一个乐高积木套装,你可以用它轻松地搭建出复杂的神经网络。Keras背后有强大的后端支持,比如TensorFlow,它负责处理底层的数学运算。

用Keras搭建神经网络非常简单。

你只需要定义每一层的类型和参数,然后Keras会帮你完成剩下的工作。比如,我们要搭建一个简单的神经网络来识别手写数字,只需要几行代码:

from keras import models
from keras import layers

model = models.Sequential()
model.add(layers.Dense(512, activation='relu', input_shape=(28 * 28,)))
model.add(layers.Dense(10, activation='softmax'))

这里,我们用 Sequential 模型,它是一个线性堆叠的层。第一层是一个Dense层,有512个神经元,使用ReLU激活函数。最后一层是一个Dense层,有10个神经元,对应10个数字类别,使用softmax激活函数。

Keras还支持更复杂的网络结构。

比如,你可以用函数式API来定义更复杂的网络,比如多输入、多输出的网络。不过,对于初学者来说, Sequential 模型已经足够用了。


3.3 建立深度学习工作站

在开始训练神经网络之前,我们需要一个合适的工作环境。

你可以用一台普通的电脑来运行Keras,但如果想更快地训练模型,最好有一块好的GPU。GPU就像是一个超级计算器,可以大大加快训练速度。如果你没有GPU,也可以在云端运行Keras,比如AWS或Google Cloud。

推荐使用Jupyter Notebook。

Jupyter Notebook是一个非常方便的工具,你可以在浏览器里运行Python代码,还可以添加文字说明,非常适合做实验和学习。

安装Keras也很简单。

你可以用pip命令来安装Keras和TensorFlow:

pip install keras
pip install tensorflow

如果你用的是GPU版本的TensorFlow,还需要安装CUDA和cuDNN,这些是NVIDIA提供的深度学习工具。


3.4 电影评论分类:二分类问题

下面我们用一个具体的例子来展示如何用神经网络解决实际问题。

假设你有一堆电影评论,每条评论都有一个标签,表示这条评论是正面的还是负面的。你想让计算机自动判断评论的情感倾向。这是一个典型的二分类问题。

我们用IMDB数据集来训练模型。

IMDB数据集包含25,000条正面评论和25,000条负面评论。每条评论都被转换成一个整数序列,每个整数代表一个单词。

from keras.datasets import imdb

(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)

这里, num_words=10000 表示我们只保留数据中前10,000个最常见的单词。

在训练模型之前,我们需要对数据进行预处理。

我们需要将整数序列转换成浮点数张量,因为神经网络只能处理浮点数。我们用one-hot编码来实现这一点:

import numpy as np

def vectorize_sequences(sequences, dimension=10000):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1.
    return results

x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

我们还需要将标签转换成浮点数:

y_train = np.asarray(train_labels).astype('float32')
y_test = np.asarray(test_labels).astype('float32')

接下来,我们构建一个简单的神经网络。

这个网络包含两个Dense层,每层有16个神经元,使用ReLU激活函数。最后一层是一个Dense层,有一个神经元,使用sigmoid激活函数,输出评论是正面的概率。

model = models.Sequential()
model.add(layers.Dense(16, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

然后,我们需要编译模型。

我们选择 rmsprop 作为优化器, binary_crossentropy 作为损失函数, accuracy 作为评估指标。

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

在训练模型之前,我们需要划分出一个验证集。

验证集用来评估模型在新数据上的表现,防止过拟合。

x_val = x_train[:10000]
partial_x_train = x_train[10000:]

y_val = y_train[:10000]
partial_y_train = y_train[10000:]

最后,我们开始训练模型。

我们训练20个epoch,每次处理512个样本。

history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=20,
                    batch_size=512,
                    validation_data=(x_val, y_val))

训练完成后,我们在测试集上评估模型的性能。

test_loss, test_acc = model.evaluate(x_test, y_test)
print('Test accuracy:', test_acc)

结果怎么样呢?

你会发现,这个简单的神经网络在测试集上的准确率可以达到88%左右。这说明神经网络能够很好地学习评论的情感倾向。


3.5 新闻分类:多分类问题

下面我们再来看一个更复杂的问题:新闻分类。

假设你有一堆新闻文章,每篇文章都有一个标签,表示它属于哪个主题。你想让计算机自动判断文章的主题。这是一个典型的多分类问题。

我们用路透社数据集来训练模型。

路透社数据集包含46个主题的新闻文章。每篇文章都被转换成一个整数序列,每个整数代表一个单词。

from keras.datasets import reuters

(train_data, train_labels), (test_data, test_labels) = reuters.load_data(num_words=10000)

在训练模型之前,我们需要对数据进行预处理。

我们需要将整数序列转换成浮点数张量,因为神经网络只能处理浮点数。我们用one-hot编码来实现这一点:

def vectorize_sequences(sequences, dimension=10000):
    results = np.zeros((len(sequences), dimension))
    for i, sequence in enumerate(sequences):
        results[i, sequence] = 1.
    return results

x_train = vectorize_sequences(train_data)
x_test = vectorize_sequences(test_data)

我们还需要将标签转换成浮点数:

from keras.utils.np_utils import to_categorical

y_train = to_categorical(train_labels)
y_test = to_categorical(test_labels)

接下来,我们构建一个简单的神经网络。

这个网络包含两个Dense层,每层有64个神经元,使用ReLU激活函数。最后一层是一个Dense层,有46个神经元,使用softmax激活函数,输出文章属于每个主题的概率。

model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(10000,)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(46, activation='softmax'))

然后,我们需要编译模型。

我们选择 rmsprop 作为优化器, categorical_crossentropy 作为损失函数, accuracy 作为评估指标。

model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

在训练模型之前,我们需要划分出一个验证集。

验证集用来评估模型在新数据上的表现,防止过拟合。

x_val = x_train[:1000]
partial_x_train = x_train[1000:]

y_val = y_train[:1000]
partial_y_train = y_train[1000:]

最后,我们开始训练模型。

我们训练20个epoch,每次处理512个样本。

history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=20,
                    batch_size=512,
                    validation_data=(x_val, y_val))

训练完成后,我们在测试集上评估模型的性能。

test_loss, test_acc = model.evaluate(x_test, y_test)
print('Test accuracy:', test_acc)

这个简单的神经网络在测试集上的准确率可以达到79%左右。这说明神经网络能够很好地学习文章的主题。


3.6 预测房价:回归问题

下面我们再来看一个完全不同的问题:预测房价。

假设你有一些关于房子的信息,比如面积、房间数量、位置等,你想让计算机预测房子的价格。这是一个典型的回归问题。

我们用波士顿房价数据集来训练模型。

波士顿房价数据集包含506个样本,每个样本有13个特征,比如人均犯罪率、平均房间数等。目标是预测房子的中位数价格。

from keras.datasets import boston_housing

(train_data, train_targets), (test_data, test_targets) = boston_housing.load_data()

在训练模型之前,我们需要对数据进行标准化。

因为不同特征的取值范围不同,我们需要将每个特征的均值变为0,标准差变为1。这样可以让神经网络的学习过程更加稳定。

mean = train_data.mean(axis=0)
train_data -= mean
std = train_data.std(axis=0)
train_data /= std

test_data -= mean
test_data /= std

接下来,我们构建一个简单的神经网络。

这个网络包含两个Dense层,每层有64个神经元,使用ReLU激活函数。最后一层是一个Dense层,没有激活函数,直接输出预测的价格。

model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(train_data.shape[1],)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(1))

然后,我们需要编译模型。

我们选择 rmsprop 作为优化器, mse (均方误差)作为损失函数, mae (平均绝对误差)作为评估指标。

model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])

在训练模型之前,我们需要划分出一个验证集。

验证集用来评估模型在新数据上的表现,防止过拟合。

x_val = train_data[:100]
partial_x_train = train_data[100:]

y_val = train_targets[:100]
partial_y_train = train_targets[100:]

最后,我们开始训练模型。

我们训练100个epoch,每次处理16个样本。

history = model.fit(partial_x_train,
                    partial_y_train,
                    epochs=100,
                    batch_size=16,
                    validation_data=(x_val, y_val))

训练完成后,我们在测试集上评估模型的性能。

test_loss, test_mae = model.evaluate(test_data, test_targets)
print('Test MAE:', test_mae)

这个神经网络模型在测试集上的平均绝对误差大约是2.55千美元。


总结

本讲我们重点介绍了神经网络的核心组件,了解了层的概念和功能。我们还学习了如何用Keras搭建神经网络,以及如何训练和评估模型。通过三个具体的例子,我们展示了神经网络在二分类问题、多分类问题和回归问题中的应用。

神经网络是深度学习的核心工具,它可以自动从数据中学习规律,解决各种复杂的问题。