C# - 3층 구조의 신경망
아래의 책에 보면,
실체가 손에 잡히는 딥러닝
; http://www.yes24.com/Product/Goods/74258238
3층 신경만을 표현한 파이썬 용 소스 코드가 나오는데 다음과 같습니다.
# http://nanya-kanya.net/index.php/1232/#outline__1_29
import numpy as np
import matplotlib.pyplot as plt
X = np.arange(-1.0, 1.0, 0.2)
Y = np.arange(-1.0, 1.0, 0.2)
Z = np.zeros((10, 10))
w_im = np.array([[2.0, -2.0],
[1.0, 4.0]])
w_mo = np.array([[1.0],
[-1.0]])
b_im = np.array([3.0, -3.0])
b_mo = np.array([0.1])
def middle_layer(x, w, b):
u = np.dot(x, w) + b
return 1 / (1 + np.exp(-u))
def output_layer(x, w, b):
u = np.dot(x, w) + b
return u
for i in range(10):
for j in range(10):
inp = np.array([X[i], Y[j]])
mid = middle_layer(inp, w_im, b_im)
out = output_layer(mid, w_mo, b_mo)
Z[j][i] = out[0]
plt.imshow(Z, "gray", vmin = 0.0, vmax = 1.0)
plt.colorbar()
plt.show()
C#으로 표현한 후,
using MathNet.Numerics.LinearAlgebra;
using System;
using System.Linq;
using np = PythonUtils;
using vector = MathNet.Numerics.LinearAlgebra.Vector<double>;
using matrix = MathNet.Numerics.LinearAlgebra.Matrix<double>;
class Program
{
static void Main(string[] args)
{
var X0 = np.arange(-1.0, 1.0, 0.2).ToArray();
var X1 = np.arange(-1.0, 1.0, 0.2).ToArray();
double[,] Y = new double[X0.Length, X1.Length];
matrix w_im = GetMatrix(new[] { -4.0, 4.0 }, new[] { -4.0, -4.0 });
matrix w_mo = GetMatrix(new[] { 1.0 }, new[] { -1.0 });
vector b_im = GetVector(3.0, -3.0);
vector b_mo = GetVector(0.1);
Func<vector, matrix, vector, vector> middle_layer = (x, w, b) =>
{
vector u = x * w + b;
return 1 / (1 + np.exp(-u));
};
Func<vector, matrix, vector, vector> output_layer = (x, w, b) =>
{
return x * w + b;
};
for (int i = 0; i < X0.Length; i++)
{
for (int j = 0; j < X1.Length; j++)
{
var inp = GetVector(X0[i], X1[j]);
var mid = middle_layer(inp, w_im, b_im);
var outp = output_layer(mid, w_mo, b_mo);
Y[j, i] = outp[0];
}
}
OutputImage("layer3_neuron.png");
void OutputImage(string fileName)
{
Gridmap grid = new Gridmap(371, 371);
grid.Show(Y, fileName);
}
}
private static Matrix<double> GetMatrix(params double[][] values)
{
return CreateMatrix.DenseOfRows(values.Length, values[0].Length, values);
}
private static Vector<double> GetVector(params double [] values)
{
return CreateVector.DenseOfArray(values);
}
}
실행해 보면, 좌측의 출력은 matplotlib의 출력이고 우측은 C# 출력입니다.
제 경우에, 신경망 출력의 값을 단순히 다음과 같이 gray 색으로 보간했는데,
double minX = gridmap.Min();
double maxX = gridmap.Max();
Func<double, double> lerf = (value) =>
{
return (value - minX) / (maxX - minX);
};
for (int i = 0; i < count; i++)
{
double h, l, s;
double r1, g1, b1;
h = 0;
l = lerf(gridmap[i]);
s = 0;
pl.hlsrgb(h, l, s, out r1, out g1, out b1);
r[i + 16] = (int)(r1 * 255.0);
g[i + 16] = (int)(g1 * 255.0);
b[i + 16] = (int)(b1 * 255.0);
}
matplotlib과 차이가 납니다. 어쩌면 보간 방식의 차이일 수도 있고, HLS to RGB 방식의 차이일 수 있는데 중요한 것은 신경망 출력이 가중치와 편향에 따라 다양해진다는 점이므로 넘어가도 좋겠습니다.
(
첨부 파일은 이 글의 예제 코드를 포함합니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]