Advertisement

Keras for Beginners: Building a Basic Neural Network.

阅读量:

作者:禅与计算机程序设计艺术

1.简介

Keras作为首个开放源代码框架,在深度学习领域具有重要地位。它不仅能够快速实现基于深度学习模型的开发,并借助GPU进行加速计算。这本教程旨在教给您掌握Keras的基本概念,并指导您在PyTorch中搭建基础神经网络。

2.Keras 简介

Keras 被认为是深度学习领域中最具影响力的主要框架之一。
它提供了高度抽象且易于使用的API,
使用户能够构建和训练复杂的神经网络架构,
无需深入处理底层代码细节。
在Keras 中,
层 作为神经网络的基本构建单元,
其作用相当于将输入数据转化为输出数据的过程。
模型 由多个层组成,
通过将各层进行组合连接构建更为复杂的网络架构。
编译器 用于配置并优化训练过程中的各种参数设置,
例如优化器、损失函数等参数。
而回调函数 则是在神经网络训练过程中执行特定功能的任务。

相对于其他框架来说,Keras以其易于上手和高度可定制的特性脱颖而出。通过几行简洁的代码就能搭建一个基础的神经网络架构,并在训练阶段使用fit()方法即可完成模型的优化过程。借助GPU资源可以显著提升Keras的训练速度,并从而使得处理大规模数据集成为一种可行的选择。此外,在机器学习领域中提供了大量经过预先训练优化的标准模型模块供开发者灵活运用。

Keras中的张量计算引擎(TensorFlow、Theano或CNTK)支持多维数据处理,并可在CPU和GPU上高效运行。此外,该系统可迅速执行多种运算过程:矩阵乘法、卷积运算以及归一化操作等基础步骤。此外,它还集成了内置激活函数与池化层结构,并支持填充操作以维持数据完整性。

此外,在Keras中包含了一系列的可视化功能模块, 可以直观显示网络结构和训练指标. 这些功能都支持在Jupyter Notebook中实现. 由此可见, 初学者或资深者只需掌握几个核心概念即可熟练运用Keras进行深度学习.

3.基本概念

下面我们将对Keras中一些重要的概念进行详细介绍:

3.1 层(Layers)

在神经网络中,层被视为最基本的功能模块。每个层都可视为输入数据经过特定变换后生成的输出数据,并赋予其相应的权重参数。Keras支持多种类型的层次组件包括卷积型层次组件Conv2D全连接型层次组件Dense批量归一化型层次组件BatchNormalization丢弃型层次组件Dropout以及最大值池化型层次组件MaxPooling2D等。每个层次组件均可根据需求设置相关参数如卷积核尺寸过滤器数量步长等关键属性以实现特定的功能需求。

3.2 模型(Models)

该模型由多个层构成。通过将各层依次连接即可构建更为复杂的网络架构。Keras提供了三种构建深度学习模型的方法:顺序堆叠、模块化设计以及整合编译器。其中顺序堆叠仅限于构造线性层次结构;而模块化设计则允许我们将整个系统划分为输入端、若干中间处理环节以及输出结果;最后整合编译器这一方案则不仅能够整合各种基础组件,并且支持完整的训练流程。

3.3 编译器(Compilers)

编译器负责设置训练过程的相关参数。这些参数主要包括优化器、损失函数以及指标函数等核心组件。编译器通常会调用 model.compile 方法来完成这一配置工作。此外,在实际应用中还可以通过直接修改模型的 optimizer 属性、 loss 属性或 metrics 属性来完成参数设置。

3.4 回调函数(Callbacks)

在训练过程中负责完成特定任务的是回调函数。Keras 包含 Callbacks 类这一功能模块,在其中定义了一些标准回调机制如 EarlyStopping、ModelCheckpoint 和 ReduceLROnPlateau 等,在训练过程中可以根据模型的关键性能指标(包括准确率、损失值以及F1分数等)来调节训练进程。通过 callbacks 参数传递给 fit() 函数后即可使用这些回调机制。

4.基于Keras的MNIST数字识别例子

为了更好地通过一个基于MNIST手写数字分类任务来感受Keras的强大功能,并在开始之前导入必要的库模块。

复制代码
    import tensorflow as tf
    from tensorflow import keras
    from tensorflow.keras import layers
    
    print("TensorFlow version:",tf.__version__)
    print("Keras version:",keras.__version__)
    
      
      
      
      
      
    
    代码解读
复制代码
    TensorFlow version: 2.3.1
    Keras version: 2.4.3
    
      
    
    代码解读

我们加载mnist数据集,数据已经被划分好了训练集、测试集和验证集。

复制代码
    (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
    
    x_train = x_train.reshape((60000, 28*28))
    x_test = x_test.reshape((10000, 28*28))
    x_train, x_val = x_train[:50000], x_train[50000:]
    y_train, y_val = y_train[:50000], y_train[50000:]
    
    print("Training set:", x_train.shape, y_train.shape)
    print("Validation set:", x_val.shape, y_val.shape)
    print("Test set:", x_test.shape, y_test.shape)
    
      
      
      
      
      
      
      
      
      
    
    代码解读
复制代码
    Training set: (60000, 784) (60000,)
    Validation set: (10000, 784) (10000,)
    Test set: (10000, 784) (10000,)
    
      
      
    
    代码解读

接下来,构建模型,使用Sequential模型。

复制代码
    model = keras.Sequential([
    layers.Dense(units=64, activation='relu', input_dim=28 * 28),
    layers.Dense(units=10, activation='softmax')
    ])
    
    model.summary() # 查看模型概要信息
    
      
      
      
      
      
    
    代码解读
复制代码
    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    dense (Dense)                (None, 64)                1792      
    _________________________________________________________________
    dense_1 (Dense)              (None, 10)                650       
    =================================================================
    Total params: 2,442
    Trainable params: 2,442
    Non-trainable params: 0
    _________________________________________________________________
    
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

进行模型的构建与训练时,采用SparseCategoricalCrossentropy损失函数,并选用Adam优化器。

复制代码
    model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
    
      
      
    
    代码解读

训练模型,这里使用验证集监控模型的训练进度。

复制代码
    history = model.fit(x_train,
                    y_train,
                    epochs=10,
                    validation_data=(x_val, y_val))
    
      
      
      
    
    代码解读
复制代码
    Epoch 1/10
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py:3485: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
      return op(self._outputs[0], other)
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/indexed_slices.py:365: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.
      "Converting sparse IndexedSlices to a dense Tensor of unknown shape. "
    WARNING:tensorflow:sample_weight modes were coerced from
    
      
      
      
      
      
      
      
    
    代码解读

将参数设置为None时,请按照以下步骤进行更新:

  • 当输入数据采用批处理模式时,请将样本权重模式指定为'temporal'。
    例如,在模型训练时,请参考下述代码片段:
    model.fit(batch_size=16, ..., sample_weight_mode='temporal')
    当调用fit()函数并提供steps_per_epoch或validation_steps参数时,请注意这可能导致错误。
复制代码
    ---------------------------------------------------------------------------
    
    KeyboardInterrupt                         Traceback (most recent call last)
    
    <ipython-input-13-fdcc3fc71bf6> in <module>()
      6               validation_data=(x_val, y_val))
    ----> 7 history = model.fit(x_train,
      8                     y_train,
    
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)
       1083         max_queue_size=max_queue_size,
       1084         workers=workers,
    -> 1085         use_multiprocessing=use_multiprocessing)
       1086 
       1087     @trackable.no_automatic_dependency_tracking
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in _method_wrapper(self, *args, **kwargs)
    640     self._self_setattr_tracking = False  # pylint: disable=protected-access
    641     try:
    --> 642       return method(self, *args, **kwargs)
    643     finally:
    644       self._self_setattr_tracking = previous_value  # pylint: disable=protected-access
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_batch_size, validation_freq, max_queue_size, workers, use_multiprocessing)
       1033           training_logs = run_compiler(
       1034               model,
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

--> 内部函数self._compile_inputs接收四个参数:x、y、sample_weights以及mask。
当validation_data为空时,默认设置val_logs为None;否则,则执行run_compiler操作应用于当前模型。

复制代码
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py in _run_CompiledNetwork(self, inputs, targets, sample_weights, masks, training)
    985         fetches = self.predict_function.call_and_update_losses(
    986             ops.convert_to_tensor_or_dataset(inputs),
    --> 987             targets, sample_weights, masks)
    988 
    989       if not isinstance(fetches, list):
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/distribute/predict_distributed_utils.py in call_and_update_losses(strategy, iterator, distributed_function, args)
     94   """Calls and updates losses."""
     95 
    ---> 96   losses = strategy.experimental_run_v2(distributed_function, args=args)
     97 
     98   def allreduce():
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py in experimental_run_v2(self, fn, args, kwargs)
       1210   
       1211       results = self._grouped_call(
    -> 1212          grouped_fn, args=args, kwargs=kwargs)
       1213 
       1214       if not self._require_all_reduced:
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py in _grouped_call(self, grouped_fn, args, kwargs)
       1297       per_replica_results = []
       1298       for group in self._groupings:
    -> 1299         sub_results = _local_per_device_graph_run(getattr(group, "_name", "default"), *args, **kwargs)
       1300         per_replica_results.append(sub_results)
       1301 
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/mirrored_run.py in _local_per_device_graph_run(devices, fn, args, kwargs)
    621   values, device_map = zip(*captured)
    622 
    --> 623   outputs = ctx.invoke_per_replica(list(zip(values, devices))[::-1], fn, kwargs)
    624 
    625   local_return_values = [_get_single_value_for_scope(i, v, device_map, output)
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/mirrored_run.py in invoke_per_replica(self, arg_tuples, replica_fn, replica_kwargs)
     55         per_replica_outs = []
     56         for i, arg_tuple in enumerate(arg_tuples):
    ---> 57           out = replica_fn(**{k: v for k, v in dict(arg_tuple).items()})
     58           per_replica_outs.append(out)
     59     
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/def_function.py in wrapped_fn(*args, **kwds)
    582         )
    583         elif self._do_captures:
    --> 584           capture_record = self._maybe_capture(args, kwds)
    585 
    586         compiled_fn = self._stateful_fn._get_concrete_function_internal_garbage_collected(  # pylint: disable=protected-access
    
    
    /usr/local/lib/python3.6/dist-packages/tensorflow/python/eager/def_function.py in _maybe_capture(self, args, kwds)
       1340         closure = grad_state.tape.gradient_function(
       1341             outputs, captured_inputs, tape._watch_targets())  # pylint: disable=protected-access
    -> 1342         arg_vals = _concatenate(args, captured_inputs)
       1343         arg_vars, captured_mask = _capture_helper(closure, len(arg_vals))
       1344         # Use identity_n ops to assign captured variables to appropriate arguments.
    
    
    ValueError: Cannot concatenate tensors with shapes [(None, 784), (None, 784)], because they are different ranks.
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读

这个错误是由于批量大小的问题导致的。

全部评论 (0)

还没有任何评论哟~