我是靠谱客的博主 自然水壶,最近开发中收集的这篇文章主要介绍在BSV上运行深度神经网络,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我们已经实现了一个用于手写数字分类的深度神经网络。已经训练好的模型完全在链上运行。它使用手写数字的 MNIST 数据集进行离线训练。该模型采用 28x28 灰度像素的图像并输出 09 的数字。

在这里插入图片描述

深度神经网络简介

人工神经网络是受生物神经网络启发而构建的。网络通过接触大量带标签的数据示例来学习。这个过程也称为监督学习。

该网络由几个组件组成:神经元/节点、连接、偏差和激活函数。这些组件被连续分组到层中。第一层称为“输入层”,数据通过该层传入网络,最后一层称为“输出层”,网络通过该层返回其输出。一个非常简单的神经网络只包含这两层。为了提高性能,我们可以在两者之间添加一个或多个“隐藏层”。具有隐藏层的网络称为“深度神经网络”(DNN)。

在这里插入图片描述

深度神经网络的图示

网络中神经元之间的每个连接都用特定值加权。每个神经元还有一个称为“偏差”的值,该值会添加到其输入的总和中。学习是找到一组这些权重和偏差的过程,这样网络将在给定一些输入的情况下返回有意义的输出。

为了直观地了解深层神经网络的工作原理,我们建议您观看有关该主题的短视频系列。

网络架构

MNIST 手写数字的 DNN 由 784 (28 x 28) 个节点的输入层、64 个节点的隐藏层和 10 个节点的输出层(可能的类/数字的数量)组成。这些层都是全连接的,这使得网络总共包含 501760 (784 * 64 * 10) 个连接。

在这里插入图片描述

隐藏层中的节点使用 ReLU 激活函数。 Argmax 用于输出节点以获得正确的值,即分类的数字。

训练模型

DNN 使用 Keras 进行训练。通过我们概述的网络架构并使用 RMSprop 优化器进行训练,该模型能够在 50 个时期后达到 98% 的分类准确率。


import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
# Model / data parameters
num_pixels = 28 * 28
num_nodes_hl = 64
num_classes = 10
batch_size = 469
epochs = 50
# Load the data and split it between train and test sets.
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Reshape images to [784, 1] and scale them to the [0, 1] range.
x_train = x_train.reshape(x_train.shape[0], num_pixels).astype("float32") / 255
x_test = x_test.reshape(x_test.shape[0], num_pixels).astype("float32") / 255
# Model
model = keras.Sequential([layers.Dense(num_nodes_hl, activation="relu"),
layers.Dense(num_classes, activation="softmax")
])
model.compile(loss="sparse_categorical_crossentropy", optimizer="rmsprop", metrics=["accuracy"])
model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_split=0.1)

训练模型后,必须以我们可以在 sCrypt 智能合约中使用的格式来导出权重和偏差。出于性能原因,我们将这些值编码为 bytes 字节,而不是数组。

实现

我们已经实现了上面的 DNN,类似于我们之前实现的单层神经网络(又名感知器)。完整的代码可以在 GitHub 上找到。

import "../train/modelParams.scrypt";
library Model {
static function applyWeights0(int[ModelParams.N_INPUTS] in) : int[ModelParams.N_NODES_HL] {
int[ModelParams.N_NODES_HL] res = repeat(0, ModelParams.N_NODES_HL);
loop (ModelParams.N_NODES_HL) : i {
int sum = 0;
loop (ModelParams.N_INPUTS) : j {
sum += (ModelParams.getWeight0(i, j) * in[j]) / 100000000;
}
res[i] = sum;
}
return res;
}
static function applyWeights1(int[ModelParams.N_NODES_HL] in) : int[ModelParams.N_NODES_OUT] {
int[ModelParams.N_NODES_OUT] res = repeat(0, ModelParams.N_NODES_OUT);
loop (ModelParams.N_NODES_OUT) : i {
int sum = 0;
loop (ModelParams.N_NODES_HL) : j {
sum += (ModelParams.getWeight1(i, j) * in[j]) / 100000000;
}
res[i] = sum;
}
return res;
}
static function addBiases0(int[ModelParams.N_NODES_HL] in) : int[ModelParams.N_NODES_HL] {
int[ModelParams.N_NODES_HL] res = repeat(0, ModelParams.N_NODES_HL);
loop (ModelParams.N_NODES_HL) : i {
res[i] = in[i] + ModelParams.getBias0(i);
}
return res;
}
static function addBiases1(int[ModelParams.N_NODES_OUT] in) : int[ModelParams.N_NODES_OUT] {
int[ModelParams.N_NODES_OUT] res = repeat(0, ModelParams.N_NODES_OUT);
loop (ModelParams.N_NODES_OUT) : i {
res[i] = in[i] + ModelParams.getBias1(i);
}
return res;
}
static function applyReLU(int[ModelParams.N_NODES_HL] in) : int[ModelParams.N_NODES_HL] {
int[ModelParams.N_NODES_HL] res = repeat(0, ModelParams.N_NODES_HL);
loop (ModelParams.N_NODES_HL) : i {
int inVal = in[i];
if (inVal > 0) {
res[i] = inVal;
}
}
return res;
}
static function predict(int[ModelParams.N_INPUTS] inputs) : int {
int[ModelParams.N_NODES_HL] step0 = applyWeights0(inputs);
int[ModelParams.N_NODES_HL] step1 = addBiases0(step0);
int[ModelParams.N_NODES_HL] step2 = applyReLU(step1);
int[ModelParams.N_NODES_OUT] step3 = applyWeights1(step2);
int[ModelParams.N_NODES_OUT] step4 = addBiases1(step3);
int idxMaxVal = 0;
int maxVal = step4[0];
loop (ModelParams.N_NODES_OUT) : i {
int outVal = step4[i];
if (outVal > maxVal) {
idxMaxVal = i;
maxVal = outVal;
}
}
return idxMaxVal;
}
}

函数 predict() 接受输入层的初始值。在我们的例子中,这是手写图像的序列化值。它返回一个代表分类结果的整数,即图像上的数字。

因为 sCrypt 不支持原生浮点数,所以我们通过简单地将值缩放 10⁸ 来使用定点表示。例如,0.86758491 变成整数 86758491。当将两个值相乘时,我们重新缩放结果,即除以 10⁸。

潜在用例

像这样的 DNN 可以在智能合约中以多种方式使用。例如,您可以训练模型以一定的准确度识别图像中是否包含热狗。鼓励用户在互联网上搜索此类照片,并自动通过提交这些照片获得比特币小额支付。可以收集这些照片来训练模型并提高其准确性。

最后

以上就是自然水壶为你收集整理的在BSV上运行深度神经网络的全部内容,希望文章能够帮你解决在BSV上运行深度神经网络所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部