# TensorFlow.NET机器学习入门【4】采用神经网络处理分类问题

上一篇文章我们介绍了通过神经网络来处理一个非线性回归的问题，这次我们将采用神经网络来处理一个多元分类的问题。

1、收集数据

2、构建神经网络

3、训练网络

4、保存和消费模型

详细步骤如下：

## 1、收集数据

        /// <summary>
/// 加载训练数据
/// </summary>
/// <param name="total_size"></param>
private (NDArray, NDArray) PrepareData(int total_size)
{
float[,] arrx = new float[total_size, num_features];
int[] arry = new int[total_size];

for (int i = 0; i < total_size; i++)
{
float weight = (float)random.Next(30, 100) / 100;
float height = (float)random.Next(140, 190) / 100;
float bmi = (weight * 100) / (height * height);

arrx[i, 0] = weight;
arrx[i, 1] = height;

switch (bmi)
{
case var x when x < 18.0f:
arry[i] = 0;
break;

case var x when x >= 18.0f && x <= 28.0f:
arry[i] = 1;
break;

case var x when x > 28.0f:
arry[i] = 2;
break;
}
}

## 2、构建神经网络

// 网络参数
int num_features = 2; // data features
int num_classes = 3; // total output

        /// <summary>
/// 构建网络模型
/// </summary>
private Model BuildModel()
{
// 网络参数
int n_hidden_1 = 64; // 1st layer number of neurons.
int n_hidden_2 = 64; // 2nd layer number of neurons.

var model = keras.Sequential(new List<ILayer>
{
keras.layers.InputLayer(num_features),
keras.layers.Dense(n_hidden_1, activation:keras.activations.Relu),
keras.layers.Dense(n_hidden_2, activation:keras.activations.Relu),
keras.layers.Dense(num_classes, activation:keras.activations.Softmax)
});

return model;
}

## 3、训练网络

            (NDArray train_x, NDArray train_y) = PrepareData(1000);
loss: keras.losses.SparseCategoricalCrossentropy(),
metrics: new[] { "accuracy" });
model.fit(train_x, train_y, batch_size: 128, epochs: 300);

        private Tensor BinaryCrossentropy(Tensor x, Tensor y)
{
var shape = tf.reduce_prod(tf.shape(x));
var count = tf.cast(shape, TF_DataType.TF_FLOAT);
x = tf.clip_by_value(x, 1e-6f, 1.0f - 1e-6f);
var z = y * tf.log(x) + (1 - y) * tf.log(1 - x);
var result = -1.0f / count * tf.reduce_sum(z);
return result;
}

## 4、保存和消费模型

        /// <summary>
/// 消费模型
/// </summary>
private void test(Model model)
{
int test_size = 20;
for (int i = 0; i < test_size; i++)
{
float weight = (float)random.Next(40, 90) / 100;
float height = (float)random.Next(145, 185) / 100;
float bmi = (weight * 100) / (height * height);

var test_x = np.array(new float[1, 2] { { weight, height } });
var pred_y = model.Apply(test_x);

Console.WriteLine($"{i}:weight={(float)weight} \theight={height} \tBMI={bmi:0.0} \tPred:{pred_y[0].numpy()}"); } } 下面为测试结果： 随便看两条数据：当BMI为30.5时，预测结果为[0,0.0016,0.9983]；当BMI为12.5时，预测结果为：[1,0,0]，可见结果还是准确的。 全部代码如下：  /// <summary> /// 通过神经网络来实现多元分类 /// </summary> public class NN_MultipleClassification_BMI { private readonly Random random = new Random(1); // 网络参数 int num_features = 2; // data features int num_classes = 3; // total output . public void Run() { var model = BuildModel(); model.summary(); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); (NDArray train_x, NDArray train_y) = PrepareData(1000); model.compile(optimizer: keras.optimizers.Adam(0.001f), loss: keras.losses.SparseCategoricalCrossentropy(), metrics: new[] { "accuracy" }); model.fit(train_x, train_y, batch_size: 128, epochs: 300); test(model); } /// <summary> /// 构建网络模型 /// </summary> private Model BuildModel() { // 网络参数 int n_hidden_1 = 64; // 1st layer number of neurons. int n_hidden_2 = 64; // 2nd layer number of neurons. var model = keras.Sequential(new List<ILayer> { keras.layers.InputLayer(num_features), keras.layers.Dense(n_hidden_1, activation:keras.activations.Relu), keras.layers.Dense(n_hidden_2, activation:keras.activations.Relu), keras.layers.Dense(num_classes, activation:keras.activations.Softmax) }); return model; } /// <summary> /// 加载训练数据 /// </summary> /// <param name="total_size"></param> private (NDArray, NDArray) PrepareData(int total_size) { float[,] arrx = new float[total_size, num_features]; int[] arry = new int[total_size]; for (int i = 0; i < total_size; i++) { float weight = (float)random.Next(30, 100) / 100; float height = (float)random.Next(140, 190) / 100; float bmi = (weight * 100) / (height * height); arrx[i, 0] = weight; arrx[i, 1] = height; switch (bmi) { case var x when x < 18.0f: arry[i] = 0; break; case var x when x >= 18.0f && x <= 28.0f: arry[i] = 1; break; case var x when x > 28.0f: arry[i] = 2; break; } } return (np.array(arrx), np.array(arry)); } /// <summary> /// 消费模型 /// </summary> private void test(Model model) { int test_size = 20; for (int i = 0; i < test_size; i++) { float weight = (float)random.Next(40, 90) / 100; float height = (float)random.Next(145, 185) / 100; float bmi = (weight * 100) / (height * height); var test_x = np.array(new float[1, 2] { { weight, height } }); var pred_y = model.Apply(test_x); Console.WriteLine($"{i}:weight={(float)weight} \theight={height} \tBMI={bmi:0.0} \tPred:{pred_y[0].numpy()}");
}
}
}
View Code

【相关资源】

posted @ 2021-12-27 11:36  seabluescn  阅读(913)  评论(0编辑  收藏  举报