在本文中,我们将展示如何通过.NET来实现卷积神经网络(CNN
)模型。我们将通过此模型对MNIST数据集进行分类。
我们要构建的神经网络的结构如下, MNIST
数据的手写数字图像有10个类(从0到9),网络有2个卷积层,最后是2个全连接层。
图:神经网络架构
下面让我们一起来看看怎么实施:
1. 准备数据
MNIST
是手写数字的数据集,包含55,000个用于训练的示例,5,000个用于验证的示例和10,000个用于测试的示例。这些数字的尺寸已经标准化,并且以固定尺寸的图像(28 x 28像素)为中心,其值为0和1.每个图像已被展平并转换为784个特征的一维阵列。它也是深度学习数据集的基准。
导入TensorFlow.NET和[NumSharp](https://github.com/scisharp/numsharp)
库。
using System;
using NumSharp;
using Tensorflow;
using TensorFlowNET.Examples.Utility;
using static Tensorflow.Python;
const int img_h = 28;
const int img_w = 28;
int n_classes = 10; // Number of classes, one class per digit
int n_channels = 1;
我们将编写自动加载MNIST
数据的函数,并以我们想要的形式返回。有一个MNIST
数据助手,可以让整个过程更轻松。
Datasets mnist;
public void PrepareData()
{
mnist = MnistDataSet.read_data_sets(“mnist”,one_hot:true);
}
除了加载图像和相应标签的函数外,我们还需要三个函数:
reformat:将数据重新格式化为卷积层可接受的格式。
private (NDArray, NDArray) Reformat(NDArray x, NDArray y)
{
var (img_size, num_ch, num_class) = (np.sqrt(x.shape[1]), 1, len(np.unique<int>(np.argmax(y, 1))));
var dataset = x.reshape(x.shape[0], img_size, img_size, num_ch).astype(np.float32);
//y[0] = np.arange(num_class) == y[0];
//var labels = (np.arange(num_class) == y.reshape(y.shape[0], 1, y.shape[1])).astype(np.float32);
return (dataset, y);
}
randomize:随机化图像及其标签的顺序。在每个epoch
的开始,我们将重新随机化数据样本的顺序,以确保训练的模型对数据的顺序不敏感。
private (NDArray, NDArray) randomize(NDArray x, NDArray y)
{
var perm = np.random.permutation(y.shape[0]);
np.random.shuffle(perm);
return (mnist.train.images[perm], mnist.train.labels[perm]);
}
get_next_batch:仅选择由batch_size
变量确定的少量图像(根据Stochastic Gradient Descent
方法)。
private (NDArray, NDArray) get_next_batch(NDArray x, NDArray y, int start, int end)
{
var x_batch