[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
using System; namespace RestrictedBoltzmannMachines.Binary { class Program { static void Main(string[] args) { double[][] trainingData = { new double[]{1, 1, 1, 0, 0}, new double[]{0, 0, 1, 1, 1}, new double[]{0, 1, 1, 1, 0} }; var hiddenNeuronCount = 3; var visibleNeuronCount = trainingData[0].Length; var restrictedBoltzmannMachine = new RestrictedBoltzmannMachine( visibleNeuronCount, hiddenNeuronCount, new Random(0) ); var trainingEpochCount = 1000; var basicLearningRate = 0.1; // train for (int epoch = 0; epoch < trainingEpochCount; epoch++) { foreach (var data in trainingData) { restrictedBoltzmannMachine.SetVisibleNeuronValues(data); restrictedBoltzmannMachine.LearnFromData(basicLearningRate / trainingData.Length); } } double[][] testInputData = { new double[]{1, 1, 0, 0, 0}, new double[]{0, 0, 0, 1, 1} }; foreach (var input in testInputData) { restrictedBoltzmannMachine.SetVisibleNeuronValues(input); restrictedBoltzmannMachine.Associate(); foreach (var output in restrictedBoltzmannMachine.VisibleNeurons) { Console.Write(output.Value + " "); } Console.WriteLine(); } } } }
using System; namespace RestrictedBoltzmannMachines.Binary { public class RestrictedBoltzmannMachine { public SymmetricConnection[][] Connections; public Neuron[] HiddenNeurons; public Neuron[] VisibleNeurons; public Random Random; public RestrictedBoltzmannMachine(int visibleNeuronCount, int hiddenNeuronCount, Random random) : this(SymmetricConnection.CreateRandomWeights(random, visibleNeuronCount, hiddenNeuronCount), new double[visibleNeuronCount], new double[hiddenNeuronCount], random) { } public RestrictedBoltzmannMachine(double[][] weights, double[] visibleBiases, double[] hiddenBiases, Random random) { this.Random = random; this.VisibleNeurons = Neuron.CreateNeurons(visibleBiases); this.HiddenNeurons = Neuron.CreateNeurons(hiddenBiases); this.Connections = SymmetricConnection.CreateConnections(weights, VisibleNeurons, HiddenNeurons); Neuron.WireConnections(this.Connections); } public void SetVisibleNeuronValues(double[] visibleValues) { for (int i = 0; i < this.VisibleNeurons.Length; i++) { this.VisibleNeurons[i].Value = visibleValues[i]; } } public void LearnFromData(double learningRate, int freeAssociationStepCount = 1) { Wake(learningRate); Sleep(learningRate, freeAssociationStepCount); EndLearning(); } public void Wake(double learningRate) { updateNeurons(this.HiddenNeurons); learn(learningRate); } private void updateNeurons(Neuron[] neurons) { foreach (var neuron in neurons) { neuron.Update(Random); } } private void learn(double learningRate) { foreach (var connectionRow in this.Connections) { foreach (var connection in connectionRow) { connection.Learn(learningRate); } } foreach (var hidden in this.HiddenNeurons) { hidden.LearnAsHidden(learningRate); } foreach (var visible in this.VisibleNeurons) { visible.LearnAsVisible(learningRate); } } public void Sleep(double learningRate, int freeAssociationStepCount) { doFreeAssociation(freeAssociationStepCount); learn(-learningRate); } //Gibbs sampling private void doFreeAssociation(int freeAssociationStepCount) { for (int step = 0; step < freeAssociationStepCount; step++) { updateNeurons(this.VisibleNeurons); updateNeurons(this.HiddenNeurons); } } public void EndLearning() { foreach (var connectionRow in this.Connections) { foreach (var connection in connectionRow) { connection.EndLearning(); } } foreach (var hidden in this.HiddenNeurons) { hidden.EndLearning(); } foreach (var visible in this.VisibleNeurons) { visible.EndLearning(); } } public void Associate() { updateNeurons(this.HiddenNeurons); updateNeurons(this.VisibleNeurons); } } }
using System; using System.Collections.Generic; using System.Linq; namespace RestrictedBoltzmannMachines.Binary { public class Neuron { public double Value; public double Probability; public double Bias; public double DeltaBias; public List<Synapse> Synapses = new List<Synapse>(); public void Update(Random random) { this.Probability = sigmoid(Synapses.Sum(s => s.Connection.Weight * s.SourceNeuron.Value) + Bias); this.Value = nextBool(random, this.Probability) ? 1 : 0; } public void LearnAsVisible(double learningRate) { this.DeltaBias += learningRate * this.Value; } public void LearnAsHidden(double learningRate) { this.DeltaBias += learningRate * this.Probability; } public void EndLearning() { this.Bias += this.DeltaBias; this.DeltaBias = 0; } public static Neuron[] CreateNeurons(double[] biases) { Neuron[] result = new Neuron[biases.Length]; for (int i = 0; i < result.Length; i++) { result[i] = new Neuron { Bias = biases[i] }; } return result; } public static void WireConnections(SymmetricConnection[][] connections) { foreach (var connectionRow in connections) { foreach (var connection in connectionRow) { Synapse hiddenConnection = new Synapse(); hiddenConnection.Connection = connection; hiddenConnection.SourceNeuron = connection.VisibleNeuron; connection.HiddenNeuron.Synapses.Add(hiddenConnection); Synapse visibleConnection = new Synapse(); visibleConnection.Connection = connection; visibleConnection.SourceNeuron = connection.HiddenNeuron; connection.VisibleNeuron.Synapses.Add(visibleConnection); } } } private static double sigmoid(double x) { return 1.0 / (1.0 + Math.Exp(-x)); } private static bool nextBool(Random random, double rate) { if (rate < 0 || 1 < rate) return false; return random.NextDouble() < rate; } } }
using System; namespace RestrictedBoltzmannMachines.Binary { public class Synapse { public Neuron SourceNeuron; public SymmetricConnection Connection; } public class SymmetricConnection { public double Weight; public double DeltaWeight; public Neuron VisibleNeuron; public Neuron HiddenNeuron; public void Learn(double learningRate) { this.DeltaWeight += learningRate * VisibleNeuron.Value * HiddenNeuron.Probability; } public void EndLearning() { this.Weight += this.DeltaWeight; this.DeltaWeight = 0; } public static double[][] CreateRandomWeights(Random random, int visibleNeuronCount, int hiddenNeuronCount) { var result = createJaggedArray<double>(visibleNeuronCount, hiddenNeuronCount); double a = 1.0 / visibleNeuronCount; for (int i = 0; i < visibleNeuronCount; i++) { for (int j = 0; j < hiddenNeuronCount; j++) { result[i][j] = uniform(random, -a, a); } } return result; } private static T[][] createJaggedArray<T>(int visibleNeuronCount, int hiddenNeuronCount) { var result = new T[visibleNeuronCount][]; for (int i = 0; i < visibleNeuronCount; i++) { result[i] = new T[hiddenNeuronCount]; } return result; } private static double uniform(Random random, double min, double max) { return random.NextDouble() * (max - min) + min; } public static SymmetricConnection[][] CreateConnections(double[][] weights, Neuron[] visibleNeurons, Neuron[] hiddenNeurons) { var result = createJaggedArray<SymmetricConnection>(visibleNeurons.Length, hiddenNeurons.Length); for (int i = 0; i < visibleNeurons.Length; i++) { for (int j = 0; j < hiddenNeurons.Length; j++) { SymmetricConnection connection = new SymmetricConnection(); connection.Weight = weights[i][j]; connection.VisibleNeuron = visibleNeurons[i]; connection.HiddenNeuron = hiddenNeurons[j]; result[i][j] = connection; } } return result; } } }
1 1 1 0 0 0 0 1 1 1これは何を意味しているのでしょう?