人工智能小白日记之14 ML学习篇之10神经网络简介 Introduction to Neural Networks

前言

wow,终于到了传说中的神经网络,听起来高大上有木有。让我们揭开它神秘的面纱,想想还有点小激动呢。

那神经网络是怎么出现的呢?视频中给我们介绍了这么一个栗子:
在这里插入图片描述
当我们的问题不是简单的线性问题的时候,前面了解过可以通过特征组合的线性模型来研究非线性问题,前提是能人工找到一个恰当的组合。而现在这个螺旋的例子,很难找出一个合适的组合。

那么问题来了,有没有一种办法让模型自行学习非线性规律, 而不用我们手动为它们指定参数。而深度神经网络可以帮忙实现这些,666,有这种想法的人简直是疯子,他是怎么认为这个东西可以实现,然后发展到今天竟然真的实现了?。让我下意识的pa了一下这个过程http://www.sohu.com/a/156451377_693397

“如果要说到人工智能和深度学习的故事,那最好就是从William McCulloch和Walter Pitts开始说起了。在1943年,他们出版了一本书叫做A Logical Calculus of the Ideas Immanent in Nervous Activity。书中他们罗列了神经网络的第一个计算模型。这本书自此成为了第一个人工神经网络的蓝图。”

膜拜一下,1943年。

课程内容

1 神经网络

在这里插入图片描述
如果是个线性问题,输出是输入的组合可能就能解决问题,不行的话就加入一些“隐藏层”;如果是个非线性问题,线性再怎么组合可能也不能解决问题,这时候需要非线性转换层进行转换。

1-1 常见的激活函数

1)前面已经见过了S型函数
在这里插入图片描述
在这里插入图片描述
2)修正线性单元激活函数(简称为 ReLU)
在这里插入图片描述
如果返回值在零值以上,则为线性函数。 如果函数返回值小于零,则输出为零。
在这里插入图片描述

假设 表示我们的激活函数(ReLU、S 型函数等等)。因此,网络中节点的值由以下公式指定:
在这里插入图片描述

现在,我们的模型拥有了人们通常所说的“神经网络”的所有标准组件:

  • 一组节点,类似于神经元,位于层中。
  • 一组权重,表示每个神经网络层与其下方的层之间的关系。下方的层可能是另一个神经网络层,也可能是其他类型的层。
  • 一组偏差,每个节点一个偏差。
  • 一个激活函数,对层中每个节点的输出进行转换。不同的层可能拥有不同的激活函数。

2 练习

2-1 首个神经网络

在这里插入图片描述
ps:现在要训练这么个模型,可以看出互相参杂,有难度

在本练习中,我们将训练首个小型神经网络。借助神经网络,我们无需使用显式特征组合,便可学习非线性模型。

任务 1:给定模型将两个输入特征合并为一个神经元。此模型会学习任何非线性规律吗?运行该模型,以确认您的猜测是否正确。
猜测应该不行吧,下面的激活函数默认为线性的,根据前面所说,线性添加线性隐藏层,没有办法学习非线性规律

任务 2:尝试将隐藏层中神经元的数量从 1 增加到 2,此外,尝试将线性激活更改为非线性激活(例如 ReLU)。您能否创建可以学习非线性的模型?
在这里插入图片描述
跑了一下最后是个非线性模型,但是貌似右上角的被它忽略了,损失在0.3以上

任务 3:通过添加或移除隐藏层和每层的神经元,继续进行实验。此外,您可以随时更改学习速率、正则化和其他学习设置。要使测试损失不超过 0.177,您可以使用的最少节点和层数是多少?
随便调了一下,居然符合要求了,666,第一层3节点,第二层2节点。
在这里插入图片描述

2-2 神经网络初始化

本练习将再次使用 XOR 数据,但这次用于研究训练神经网络的重复性以及初始化的重要性。

任务 1:运行给定模型四到五次。在每次试验开始之前,请点击重置网络按钮,以获取新的随机初始化数据。(重置网络按钮是一个圆形重置箭头,位于“播放”按钮左侧)。让每次试验至少运行 500 步,以确保图形能收敛。每个模型输出会收敛为何种形状?对于初始化在非凸优化中发挥的作用,这说明了什么?

随便跑了一下,发现每次结果可能都不一样。如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

任务 2:尝试添加一层和几个额外节点,让模型变得稍微复杂点。重复任务 1 的试验。这是否可以提高结果的稳定性?

多增加层和节点后,稳定性强多了,虽然一开始模型不一样(有点类似任务1中的那几个图片),但是训练到最后的模型几乎一致,损失也很小
在这里插入图片描述

2-3 神经网络螺旋

此数据集是一种混乱的螺旋。显然,线性模型不适用于此处,但即使手动定义的特征组合可能也很难构建。

任务 1:只使用 X1 和 X2 训练您可以获得的最佳模型。您可以随时添加或移除层和神经元,以及更改学习速率、正则化率和批量大小等学习设置。您可以获得的最佳测试损失是多少?此模型输出表面的平滑程度如何?

这是我的一次训练,学习速率0.1好像太高,导致无法收敛,而且训练损失0.2,测试损失0.5相差过大,(一般训练损失减小,测试损失增加,过拟合的现象)正则化率也低了点或者换L1简化模型复杂度,微调之后会好点但是训练损失没有低于0.2.囧,可能还要再加节点,这不蛋疼吗,跑起来很慢啊喂。
在这里插入图片描述

任务 2:即使使用神经网络,通常也需要一些特征工程,才能获得最佳性能。尝试添加额外向量积特征或 sin(X1) 和 sin(X2) 等其他转换。您是否获得了更好的模型?模型输出表面是否更平滑?

不列了,太慢了。可以看看最后的视频,讲的很详细。

3 编程练习

在这里插入图片描述
学习目标:

  • 使用 TensorFlow DNNRegressor 类定义神经网络 (NN) 及其隐藏层
  • 训练神经网络学习数据集中的非线性规律,并实现比线性回归模型更好的效果

3-1 加载数据集

这步跟前面的一样

from __future__ import print_function

import math

from IPython import display
from matplotlib import cm
from matplotlib import gridspec
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
from sklearn import metrics
import tensorflow as tf
from tensorflow.python.data import Dataset

tf.logging.set_verbosity(tf.logging.ERROR)
pd.options.display.max_rows = 10
pd.options.display.float_format = '{:.1f}'.format

#如果出现证书问题,添加以下代码
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
california_housing_dataframe = pd.read_csv("https://download.mlcc.google.cn/mledu-datasets/california_housing_train.csv", sep=",")

california_housing_dataframe = california_housing_dataframe.reindex(
    np.random.permutation(california_housing_dataframe.index))

3-2 处理特征和标签

这步回到了最初线性回归的代码

def preprocess_features(california_housing_dataframe):
  """Prepares input features from California housing data set.

  Args:
    california_housing_dataframe: A Pandas DataFrame expected to contain data
      from the California housing data set.
  Returns:
    A DataFrame that contains the features to be used for the model, including
    synthetic features.
  """
  selected_features = california_housing_dataframe[
    ["latitude",
     "longitude",
     "housing_median_age",
     "total_rooms",
     "total_bedrooms",
     "population",
     "households",
     "median_income"]]
  processed_features = selected_features.copy()
  # Create a synthetic feature.
  processed_features["rooms_per_person"] = (
    california_housing_dataframe["total_rooms"] /
    california_housing_dataframe["population"])
  return processed_features

def preprocess_targets(california_housing_dataframe):
  """Prepares target features (i.e., labels) from California housing data set.

  Args:
    california_housing_dataframe: A Pandas DataFrame expected to contain data
      from the California housing data set.
  Returns:
    A DataFrame that contains the target feature.
  """
  output_targets = pd.DataFrame()
  # Scale the target to be in units of thousands of dollars.
  output_targets["median_house_value"] = (
    california_housing_dataframe["median_house_value"] / 1000.0)
  return output_targets

3-3 划分训练集和验证集

和前面一样

# Choose the first 12000 (out of 17000) examples for training.
training_examples = preprocess_features(california_housing_dataframe.head(12000))
training_targets = preprocess_targets(california_housing_dataframe.head(12000))

# Choose the last 5000 (out of 17000) examples for validation.
validation_examples = preprocess_features(california_housing_dataframe.tail(5000))
validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))

# Double-check that we've done the right thing.
print("Training examples summary:")
display.display(training_examples.describe())
print("Validation examples summary:")
display.display(validation_examples.describe())

print("Training targets summary:")
display.display(training_targets.describe())
print("Validation targets summary:")
display.display(validation_targets.describe())

3-4 特征列和输入函数

也是和线性回归中一样的

def construct_feature_columns(input_features):
  """Construct the TensorFlow Feature Columns.

  Args:
    input_features: The names of the numerical input features to use.
  Returns:
    A set of feature columns
  """ 
  return set([tf.feature_column.numeric_column(my_feature)
              for my_feature in input_features])
          
def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):
    """Trains a neural net regression model.
  
    Args:
      features: pandas DataFrame of features
      targets: pandas DataFrame of targets
      batch_size: Size of batches to be passed to the model
      shuffle: True or False. Whether to shuffle the data.
      num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely
    Returns:
      Tuple of (features, labels) for next data batch
    """
    
    # Convert pandas data into a dict of np arrays.
    features = {key:np.array(value) for key,value in dict(features).items()}                                             
 
    # Construct a dataset, and configure batching/repeating.
    ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit
    ds = ds.batch(batch_size).repeat(num_epochs)
    
    # Shuffle the data, if specified.
    if shuffle:
      ds = ds.shuffle(10000)
    
    # Return the next batch of data.
    features, labels = ds.make_one_shot_iterator().get_next()
    return features, labels

3-5 构建神经网络

神经网络由 DNNRegressor 类定义。

使用 hidden_units 定义神经网络的结构。hidden_units 参数会创建一个整数列表,其中每个整数对应一个隐藏层,表示其中的节点数。以下面的赋值为例:

hidden_units=[3,10]

上述赋值为神经网络指定了两个隐藏层:

  • 第一个隐藏层包含 3 个节点。
  • 第二个隐藏层包含 10 个节点。
    如果我们想要添加更多层,可以向该列表添加更多整数。例如,hidden_units=[10,20,30,40] 会创建 4 个分别包含 10、20、30 和 40 个单元的隐藏层。

默认情况下,所有隐藏层都会使用 ReLu 激活函数,且是全连接层。

def train_nn_regression_model(
    learning_rate,
    steps,
    batch_size,
    hidden_units,
    training_examples,
    training_targets,
    validation_examples,
    validation_targets):
  """Trains a neural network regression model.
  
  In addition to training, this function also prints training progress information,
  as well as a plot of the training and validation loss over time.
  
  Args:
    learning_rate: A `float`, the learning rate.
    steps: A non-zero `int`, the total number of training steps. A training step
      consists of a forward and backward pass using a single batch.
    batch_size: A non-zero `int`, the batch size.
    hidden_units: A `list` of int values, specifying the number of neurons in each layer.
    training_examples: A `DataFrame` containing one or more columns from
      `california_housing_dataframe` to use as input features for training.
    training_targets: A `DataFrame` containing exactly one column from
      `california_housing_dataframe` to use as target for training.
    validation_examples: A `DataFrame` containing one or more columns from
      `california_housing_dataframe` to use as input features for validation.
    validation_targets: A `DataFrame` containing exactly one column from
      `california_housing_dataframe` to use as target for validation.
      
  Returns:
    A `DNNRegressor` object trained on the training data.
  """

  periods = 10
  steps_per_period = steps / periods
  
  # Create a DNNRegressor object.
  my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)
  my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)
  dnn_regressor = tf.estimator.DNNRegressor(
      feature_columns=construct_feature_columns(training_examples),
      hidden_units=hidden_units,
      optimizer=my_optimizer
  )
  
  # Create input functions.
  training_input_fn = lambda: my_input_fn(training_examples, 
                                          training_targets["median_house_value"], 
                                          batch_size=batch_size)
  predict_training_input_fn = lambda: my_input_fn(training_examples, 
                                                  training_targets["median_house_value"], 
                                                  num_epochs=1, 
                                                  shuffle=False)
  predict_validation_input_fn = lambda: my_input_fn(validation_examples, 
                                                    validation_targets["median_house_value"], 
                                                    num_epochs=1, 
                                                    shuffle=False)

  # Train the model, but do so inside a loop so that we can periodically assess
  # loss metrics.
  print("Training model...")
  print("RMSE (on training data):")
  training_rmse = []
  validation_rmse = []
  for period in range (0, periods):
    # Train the model, starting from the prior state.
    dnn_regressor.train(
        input_fn=training_input_fn,
        steps=steps_per_period
    )
    # Take a break and compute predictions.
    training_predictions = dnn_regressor.predict(input_fn=predict_training_input_fn)
    training_predictions = np.array([item['predictions'][0] for item in training_predictions])
    
    validation_predictions = dnn_regressor.predict(input_fn=predict_validation_input_fn)
    validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])
    
    # Compute training and validation loss.
    training_root_mean_squared_error = math.sqrt(
        metrics.mean_squared_error(training_predictions, training_targets))
    validation_root_mean_squared_error = math.sqrt(
        metrics.mean_squared_error(validation_predictions, validation_targets))
    # Occasionally print the current loss.
    print("  period %02d : %0.2f" % (period, training_root_mean_squared_error))
    # Add the loss metrics from this period to our list.
    training_rmse.append(training_root_mean_squared_error)
    validation_rmse.append(validation_root_mean_squared_error)
  print("Model training finished.")

  # Output a graph of loss metrics over periods.
  plt.ylabel("RMSE")
  plt.xlabel("Periods")
  plt.title("Root Mean Squared Error vs. Periods")
  plt.tight_layout()
  plt.plot(training_rmse, label="training")
  plt.plot(validation_rmse, label="validation")
  plt.legend()

  print("Final RMSE (on training data):   %0.2f" % training_root_mean_squared_error)
  print("Final RMSE (on validation data): %0.2f" % validation_root_mean_squared_error)

  return dnn_regressor

ps:貌似代码中唯一不一样的地方就是把原来线性回归的模型替换为神经网络模型,然后指定隐藏层
在这里插入图片描述
可能有人会奇怪,说好的激活函数呢,前面说了默认为ReLu函数,而且是全联接的。那么如果我们需要指定激活函数,在哪处理呢?
去tensorflow的api文档里找一下:
在这里插入图片描述
呐,在茫茫字海中,我一眼就瞥见了它
在这里插入图片描述

3-6 任务 1:训练神经网络模型

调整超参数,目标是将 RMSE 降到 110 以下。

运行以下代码块来训练神经网络模型。

我们已经知道,在使用了很多特征的线性回归练习中,110 左右的 RMSE 已经是相当不错的结果。我们将得到比它更好的结果。

在此练习中,您的任务是修改各种学习设置,以提高在验证数据上的准确率。

对于神经网络而言,过拟合是一种真正的潜在危险。您可以查看训练数据损失与验证数据损失之间的差值,以帮助判断模型是否有过拟合的趋势。如果差值开始变大,则通常可以肯定存在过拟合。

由于存在很多不同的可能设置,强烈建议您记录每次试验,以在开发流程中进行参考。

此外,获得效果出色的设置后,尝试多次运行该设置,看看结果的重复程度。由于神经网络权重通常会初始化为较小的随机值,因此每次运行结果应该存在差异。

dnn_regressor = train_nn_regression_model(
    learning_rate=0.01,
    steps=500,
    batch_size=10,
    hidden_units=[10, 2],
    training_examples=training_examples,
    training_targets=training_targets,
    validation_examples=validation_examples,
    validation_targets=validation_targets)

在这里插入图片描述
损失离110还比较远,看来要多调一下下,加点层,提高点速率看看

dnn_regressor = train_nn_regression_model(
    learning_rate=0.1,
    steps=500,
    batch_size=10,
    hidden_units=[10,5, 2],
    training_examples=training_examples,
    training_targets=training_targets,
    validation_examples=validation_examples,
    validation_targets=validation_targets)

在这里插入图片描述
这么强?一下到位的节奏?不过再一次运行发现长这样
在这里插入图片描述
囧,这是要闹哪样,神经网络初始化对执行结果产生影响较大,可能是执行次数不够多的节奏吗,降低学习速率。同时加点节点,增大点批量

dnn_regressor = train_nn_regression_model(
    learning_rate=0.001,
    steps=2000,
    batch_size=100,
    hidden_units=[10,8, 4],
    training_examples=training_examples,
    training_targets=training_targets,
    validation_examples=validation_examples,
    validation_targets=validation_targets)

在这里插入图片描述
差不多达到任务目标了。

3-7 任务 2:用测试数据进行评估

确认您的验证效果结果经受得住测试数据的检验。

获得满意的模型后,用测试数据评估该模型,以与验证效果进行比较。

提示:测试数据集位于此处。

california_housing_test_data = pd.read_csv("https://download.mlcc.google.cn/mledu-datasets/california_housing_test.csv", sep=",")

test_examples = preprocess_features(california_housing_test_data)
test_targets = preprocess_targets(california_housing_test_data)

predict_testing_input_fn = lambda: my_input_fn(test_examples, 
                                               test_targets["median_house_value"], 
                                               num_epochs=1, 
                                               shuffle=False)

test_predictions = dnn_regressor.predict(input_fn=predict_testing_input_fn)
test_predictions = np.array([item['predictions'][0] for item in test_predictions])

root_mean_squared_error = math.sqrt(
    metrics.mean_squared_error(test_predictions, test_targets))

print("Final RMSE (on test data): %0.2f" % root_mean_squared_error)

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Introduction to Graph Neural Networks》是一本介绍图神经网络的PDF。图神经网络是一类用于处理图结构数据的深度学习模型。该PDF主要介绍了图神经网络的基本概念、结构和应用。 首先,PDF简要介绍了图神经网络的起源和发展背景。它指出传统的神经网络模型无法有效地处理图结构数据中的关系和局部信息,而图神经网络的出现填补了这一空白。 接着,PDF详细解释了图神经网络的基本概念。它提到图神经网络通过将节点和边表示为向量,利用图卷积操作来更新节点的表示,从而融合了节点的邻居信息。同时,它还介绍了图神经网络在处理无向图、有向图和多图时的不同形式和应用。 然后,PDF分析了图神经网络的结构。它介绍了常见的图神经网络结构,如Graph Convolutional Networks (GCN)、GraphSAGE和Graph Attention Networks (GAT)等。对于每种结构,PDF详细解释了其原理和在实践中的应用。 最后,PDF总结了图神经网络的应用领域。它指出图神经网络在社交网络分析、化学分子表示、推荐系统和计算机视觉等领域有广泛的应用。并且,它还提供了一些成功案例和相关论文的引用。 综上所述,《Introduction to Graph Neural Networks》这本PDF全面而详细地介绍了图神经网络的基本概念、结构和应用。对于对图神经网络感兴趣的读者来说,这本PDF是一份很好的入门资料。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值