public static double Accuracy(FunctionStack functionStack, NdArray x, NdArray y) { double matchCount = 0; NdArray forwardResult = functionStack.Predict(x)[0]; for (int b = 0; b < x.BatchCount; b++) { Real maxval = forwardResult.Data[b * forwardResult.Length]; int maxindex = 0; for (int i = 0; i < forwardResult.Length; i++) { if (maxval < forwardResult.Data[i + b * forwardResult.Length]) { maxval = forwardResult.Data[i + b * forwardResult.Length]; maxindex = i; } } if (maxindex == (int)y.Data[b * y.Length]) { matchCount++; } } return(matchCount / x.BatchCount); }
public static void Run(VGGModel modelType) { OpenFileDialog ofd = new OpenFileDialog { Filter = "画像ファイル(*.jpg;*.png;*.gif;*.bmp)|*.jpg;*.png;*.gif;*.bmp|すべてのファイル(*.*)|*.*" }; if (ofd.ShowDialog() == DialogResult.OK) { int vggId = (int)modelType; Console.WriteLine("Model Loading."); string modelFilePath = InternetFileDownloader.Donwload(Urls[vggId], FileNames[vggId], Hashes[vggId]); List <Function> vggNet = CaffemodelDataLoader.ModelLoad(modelFilePath); string[] classList = File.ReadAllLines(CLASS_LIST_PATH); //GPUを初期化 for (int i = 0; i < vggNet.Count - 1; i++) { if (vggNet[i] is CPU.Convolution2D || vggNet[i] is CPU.Linear || vggNet[i] is CPU.MaxPooling2D) { vggNet[i] = (Function)CLConverter.Convert(vggNet[i]); } } FunctionStack nn = new FunctionStack(vggNet.ToArray()); //層を圧縮 nn.Compress(); Console.WriteLine("Model Loading done."); do { //ネットワークへ入力する前に解像度を 224px x 224px x 3ch にしておく Bitmap baseImage = new Bitmap(ofd.FileName); Bitmap resultImage = new Bitmap(224, 224, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(resultImage); g.DrawImage(baseImage, 0, 0, 224, 224); g.Dispose(); Real[] bias = { -123.68, -116.779, -103.939 }; //補正値のチャンネル順は入力画像に従う(標準的なBitmapならRGB) NdArray imageArray = BitmapConverter.Image2NdArray(resultImage, false, true, bias); Console.WriteLine("Start predict."); Stopwatch sw = Stopwatch.StartNew(); NdArray result = nn.Predict(imageArray)[0]; sw.Stop(); Console.WriteLine("Result Time : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); int maxIndex = Array.IndexOf(result.Data, result.Data.Max()); Console.WriteLine("[" + result.Data[maxIndex] + "] : " + classList[maxIndex]); } while (ofd.ShowDialog() == DialogResult.OK); } }
public static void Run() { //訓練回数 const int learningCount = 10000; //訓練データ Real[][] trainData = { new Real[] { 0, 0 }, new Real[] { 1, 0 }, new Real[] { 0, 1 }, new Real[] { 1, 1 } }; //訓練データラベル Real[][] trainLabel = { new Real[] { 0 }, new Real[] { 1 }, new Real[] { 1 }, new Real[] { 0 } }; //ネットワークの構成を FunctionStack に書き連ねる FunctionStack <Real> nn = new FunctionStack <Real>( new Linear <Real>(2, 2, name: "l1 Linear"), new Sigmoid <Real>(name: "l1 ReLU"), new Linear <Real>(2, 1, name: "l2 Linear") ); //optimizerを宣言(今回はAdam) Adam <Real> adam = new Adam <Real>(); adam.SetUp(nn); //訓練ループ Console.WriteLine("Training..."); for (int i = 0; i < learningCount; i++) { //今回はロス関数にMeanSquaredErrorを使う Trainer.Train(nn, trainData[0], trainLabel[0], new MeanSquaredError <Real>()); Trainer.Train(nn, trainData[1], trainLabel[1], new MeanSquaredError <Real>()); Trainer.Train(nn, trainData[2], trainLabel[2], new MeanSquaredError <Real>()); Trainer.Train(nn, trainData[3], trainLabel[3], new MeanSquaredError <Real>()); //訓練後に毎回更新を実行しなければ、ミニバッチとして更新できる adam.Update(); } //訓練結果を表示 Console.WriteLine("Test Start..."); foreach (Real[] val in trainData) { NdArray <Real> result = nn.Predict(val)[0]; Console.WriteLine(val[0] + " xor " + val[1] + " = " + (result.Data[0] > 0.5 ? 1 : 0) + " " + result); } }
public static void Run() { OpenFileDialog ofd = new OpenFileDialog { Filter = "画像ファイル(*.jpg;*.png;*.gif;*.bmp)|*.jpg;*.png;*.gif;*.bmp|すべてのファイル(*.*)|*.*" }; if (ofd.ShowDialog() == DialogResult.OK) { Console.WriteLine("Model Loading."); string modelFilePath = InternetFileDownloader.Donwload(DOWNLOAD_URL, MODEL_FILE); List <Function> alexNet = CaffemodelDataLoader.ModelLoad(modelFilePath); string[] classList = File.ReadAllLines(CLASS_LIST_PATH); //GPUを初期化 for (int i = 0; i < alexNet.Count - 1; i++) { if (alexNet[i] is Convolution2D || alexNet[i] is Linear || alexNet[i] is MaxPooling) { ((IParallelizable)alexNet[i]).SetGpuEnable(true); } } FunctionStack nn = new FunctionStack(alexNet.ToArray()); //層を圧縮 nn.Compress(); Console.WriteLine("Model Loading done."); do { //ネットワークへ入力する前に解像度を 224px x 224px x 3ch にしておく Bitmap baseImage = new Bitmap(ofd.FileName); Bitmap resultImage = new Bitmap(227, 227, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(resultImage); g.DrawImage(baseImage, 0, 0, 227, 227); g.Dispose(); Real[] bias = { -123.68, -116.779, -103.939 }; //補正値のチャンネル順は入力画像に従う NdArray imageArray = NdArrayConverter.Image2NdArray(resultImage, false, true, bias); Console.WriteLine("Start predict."); Stopwatch sw = Stopwatch.StartNew(); NdArray result = nn.Predict(imageArray)[0]; sw.Stop(); Console.WriteLine("Result Time : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); int maxIndex = Array.IndexOf(result.Data, result.Data.Max()); Console.WriteLine("[" + result.Data[maxIndex] + "] : " + classList[maxIndex]); } while (ofd.ShowDialog() == DialogResult.OK); } }
public EvaluationResult Evaluate(EvaluationItem item) { FunctionStack <Real> nn = new FunctionStack <Real>( new Linear <Real>(NumInput, NumMiddle, false, _parameter.MiddleLayerWeight), new Linear <Real>(NumMiddle, NumOutput, false, _parameter.OutputLayerWeight) ); NdArray <Real> result = nn.Predict(item.GetReal())[0]; return(new EvaluationResult(result.Data[0])); }
public static void Run() { OpenFileDialog ofd = new OpenFileDialog { Filter = ". Image file (*. Jpg; *. Png; *. Gif; *. Bmp) | *. Jpg; *. Png; *. Gif; *. Bmp | all files (*. *) | *. *" }; if (ofd.ShowDialog() == DialogResult.OK) { Console.WriteLine("Model Loading."); string modelFilePath = InternetFileDownloader.Donwload(DOWNLOAD_URL, MODEL_FILE); List <Function> vgg16Net = CaffemodelDataLoader.ModelLoad(modelFilePath); string[] classList = File.ReadAllLines(CLASS_LIST_PATH); //Initialize GPU for (int i = 0; i < vgg16Net.Count - 1; i++) { if (vgg16Net[i] is Convolution2D || vgg16Net[i] is Linear || vgg16Net[i] is MaxPooling) { ((IParallelizable)vgg16Net[i]).SetGpuEnable(true); } } FunctionStack nn = new FunctionStack(vgg16Net.ToArray()); //Compress layer nn.Compress(); Console.WriteLine("Model Loading done."); do { //Before inputting to the network, set the resolution to 224px x 224px x 3ch Bitmap baseImage = new Bitmap(ofd.FileName); Bitmap resultImage = new Bitmap(224, 224, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(resultImage); g.DrawImage(baseImage, 0, 0, 224, 224); g.Dispose(); Real[] bias = { -123.68, -116.779, -103.939 }; //The channel order of the correction value follows the input image NdArray imageArray = NdArrayConverter.Image2NdArray(resultImage, false, true, bias); Console.WriteLine("Start predict."); Stopwatch sw = Stopwatch.StartNew(); NdArray result = nn.Predict(imageArray)[0]; sw.Stop(); Console.WriteLine("Result Time : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); int maxIndex = Array.IndexOf(result.Data, result.Data.Max()); Console.WriteLine("[" + result.Data[maxIndex] + "] : " + classList[maxIndex]); } while (ofd.ShowDialog() == DialogResult.OK); } }
public static void Run() { //Number of exercises const int learningCount = 10000; //Training data Real[][] trainData = { new Real[] { 0, 0 }, new Real[] { 1, 0 }, new Real[] { 0, 1 }, new Real[] { 1, 1 } }; //Training data label Real[][] trainLabel = { new Real[] { 0 }, new Real[] { 1 }, new Real[] { 1 }, new Real[] { 0 } }; //Writing the network configuration in FunctionStack FunctionStack nn = new FunctionStack( new Linear(2, 2, name: "l1 Linear"), new ReLU(name: "l1 ReLU"), new Linear(2, 1, name: "l2 Linear") ); //Declare optimizer (Adam in this time) nn.SetOptimizer(new Adam()); //Training loop Console.WriteLine("Training..."); for (int i = 0; i < learningCount; i++) { //This time use MeanSquaredError for loss function Trainer.Train(nn, trainData[0], trainLabel[0], new MeanSquaredError(), false); Trainer.Train(nn, trainData[1], trainLabel[1], new MeanSquaredError(), false); Trainer.Train(nn, trainData[2], trainLabel[2], new MeanSquaredError(), false); Trainer.Train(nn, trainData[3], trainLabel[3], new MeanSquaredError(), false); //If you do not update every time after training, you can update it as a mini batch nn.Update(); } //Show training results Console.WriteLine("Test Start..."); foreach (Real[] val in trainData) { NdArray result = nn.Predict(val)[0]; Console.WriteLine(val[0] + " xor " + val[1] + " = " + (result.Data[0] > 0.5 ? 1 : 0) + " " + result); } }
static Real predict_sequence(FunctionStack model, List <Real> input_seq) { model.ResetState(); NdArray result = 0; for (int i = 0; i < input_seq.Count; i++) { result = model.Predict(input_seq[i])[0]; } return(result.Data[0]); }
public static void Run() { Real[][] trainData = new Real[N][]; Real[][] trainLabel = new Real[N][]; for (int i = 0; i < N; i++) { //Sin波を一周期分用意 Real radian = -Math.PI + Math.PI * 2.0 * i / (N - 1); trainData[i] = new[] { radian }; trainLabel[i] = new Real[] { Math.Sin(radian) }; } //ネットワークの構成を FunctionStack に書き連ねる FunctionStack nn = new FunctionStack( new Linear(1, 4, name: "l1 Linear"), new TanhActivation(name: "l1 Tanh"), new Linear(4, 1, name: "l2 Linear") ); //optimizerの宣言 nn.SetOptimizer(new SGD(0.1)); //訓練ループ for (int i = 0; i < EPOCH; i++) { //誤差集計用 Real loss = 0; for (int j = 0; j < N; j++) { //ネットワークは訓練を実行すると戻り値に誤差が返ってくる loss += Trainer.Train(nn, trainData[j], trainLabel[j], new MeanSquaredError()); } if (i % (EPOCH / 10) == 0) { Console.WriteLine("loss:" + loss / N); Console.WriteLine(""); } } //訓練結果を表示 Console.WriteLine("Test Start..."); foreach (Real[] val in trainData) { Console.WriteLine(val[0] + ":" + nn.Predict(val)[0].Data[0]); } }
public static void Run() { Real[][] trainData = new Real[N][]; Real[][] trainLabel = new Real[N][]; for (int i = 0; i < N; i++) { //Prepare Sin wave for one cycle Real radian = -Math.PI + Math.PI * 2.0 * i / (N - 1); trainData[i] = new[] { radian }; trainLabel[i] = new Real[] { Math.Sin(radian) }; } //Writing the network configuration in FunctionStack FunctionStack nn = new FunctionStack( new Linear(1, 4, name: "l1 Linear"), new Tanh(name: "l1 Tanh"), new Linear(4, 1, name: "l2 Linear") ); //Declaration of optimizer nn.SetOptimizer(new SGD()); //Training loop for (int i = 0; i < EPOCH; i++) { //For error aggregation Real loss = 0; for (int j = 0; j < N; j++) { //When training is executed in the network, an error is returned to the return value loss += Trainer.Train(nn, trainData[j], trainLabel[j], new MeanSquaredError()); } if (i % (EPOCH / 10) == 0) { Console.WriteLine("loss:" + loss / N); Console.WriteLine(""); } } //Show training results Console.WriteLine("Test Start..."); foreach (Real[] val in trainData) { Console.WriteLine(val[0] + ":" + nn.Predict(val)[0].Data[0]); } }
public static void Run() { const int learningCount = 10000; Real[][] trainData = { new Real[] { 0, 0 }, new Real[] { 1, 0 }, new Real[] { 0, 1 }, new Real[] { 1, 1 } }; Real[][] trainLabel = { new Real[] { 0 }, new Real[] { 1 }, new Real[] { 1 }, new Real[] { 0 } }; FunctionStack nn = new FunctionStack("Test2", new Linear(true, 2, 2, name: "l1 Linear"), new ReLU(name: "l1 ReLU"), new Linear(true, 2, 1, name: "l2 Linear")); nn.SetOptimizer(new AdaGrad()); RILogManager.Default?.SendDebug("Training..."); for (int i = 0; i < learningCount; i++) { //use MeanSquaredError for loss function Trainer.Train(nn, trainData[0], trainLabel[0], new MeanSquaredError(), false); Trainer.Train(nn, trainData[1], trainLabel[1], new MeanSquaredError(), false); Trainer.Train(nn, trainData[2], trainLabel[2], new MeanSquaredError(), false); Trainer.Train(nn, trainData[3], trainLabel[3], new MeanSquaredError(), false); //If you do not update every time after training, you can update it as a mini batch nn.Update(); } RILogManager.Default?.SendDebug("Test Start..."); foreach (Real[] val in trainData) { NdArray result = nn.Predict(true, val)[0]; RILogManager.Default?.SendDebug($"{val[0]} xor {val[1]} = {(result.Data[0] > 0.5 ? 1 : 0)} {result}"); } }
static Real predict_sequence(FunctionStack model, List <Real> input_seq) { Ensure.Argument(model).NotNull(); Ensure.Argument(input_seq).NotNull(); model.ResetState(); NdArray result = 0; Ensure.Argument(model).NotNull(); Ensure.Argument(input_seq).NotNull(); foreach (var t in input_seq) { result = model.Predict(true, t)[0]; } return(result.Data[0]); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Accuracies. </summary> /// /// <param name="functionStack"> Stack of functions. </param> /// <param name="x"> A NdArray to process. </param> /// <param name="y"> A NdArray to process. </param> /// /// <returns> A double. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// public static double Accuracy([NotNull] FunctionStack functionStack, [NotNull] NdArray x, [CanBeNull] NdArray y, bool verbose = true) { double matchCount = 0; Stopwatch sw = new Stopwatch(); sw.Start(); if (verbose) { RILogManager.Default?.SendDebug("Running Forecast for Accuracy Prediction on " + functionStack.Name); } NdArray forwardResult = functionStack.Predict(verbose, x)[0]; for (int b = 0; b < x.BatchCount; b++) { Real maxval = forwardResult.Data[b * forwardResult.Length]; int maxindex = 0; for (int i = 0; i < forwardResult.Length; i++) { if (maxval < forwardResult.Data[i + b * forwardResult.Length]) { maxval = forwardResult.Data[i + b * forwardResult.Length]; maxindex = i; } } if (maxindex == (int)y.Data[b * y.Length]) { matchCount++; } } sw.Stop(); if (verbose) { RILogManager.Default?.SendDebug("Accuracy Prediction took " + Helpers.FormatTimeSpan(sw.Elapsed) + "ms"); RILogManager.Default?.ViewerSendWatch("Accuracy", ((matchCount / x.BatchCount) * 100).ToString() + "%", matchCount / x.BatchCount); } return(matchCount / x.BatchCount); }
public static void Run() { Real[][] trainData = new Real[N][]; Real[][] trainLabel = new Real[N][]; for (int i = 0; i < N; i++) { //Prepare Sin wave for one cycle Real radian = -Math.PI + Math.PI * 2.0 * i / (N - 1); trainData[i] = new[] { radian }; trainLabel[i] = new Real[] { Math.Sin(radian) }; } FunctionStack nn = new FunctionStack("Test3", new Linear(true, 1, 4, name: "l1 Linear"), new Tanh(name: "l1 Tanh"), new Linear(true, 4, 1, name: "l2 Linear") ); nn.SetOptimizer(new SGD()); for (int i = 0; i < EPOCH; i++) { Real loss = 0; for (int j = 0; j < N; j++) { //When training is executed in the network, an error is returned to the return value loss += Trainer.Train(nn, trainData[j], trainLabel[j], new MeanSquaredError()); } if (i % (EPOCH / 10) == 0) { RILogManager.Default?.SendDebug("loss:" + loss / N); RILogManager.Default?.SendDebug(""); } } RILogManager.Default?.SendDebug("Test Start..."); foreach (Real[] val in trainData) { RILogManager.Default?.SendDebug(val[0] + ":" + nn.Predict(true, val)[0].Data[0]); } }
private static void RunAsync() { var trainData = new NdArray(new[] { 2, 3, 4 }); for (int i = 0; i < trainData.Data.Length; i++) { trainData.Data[i] = (float)i / trainData.Data.Length; } var functions = new List <Function>(); functions.Add(new Convolution2D(2, 1, 3)); var nn = new FunctionStack(functions.ToArray()); nn.Compress(); var optimizer = new Adam(); nn.SetOptimizer(optimizer); var result = nn.Predict(trainData)[0]; }
private void button3_Click(object sender, EventArgs e) { SaveFileDialog sfd = new SaveFileDialog { Filter = "png Files(*.png)|*.png|All Files(*.*)|*.*", FileName = "result.png" }; if (sfd.ShowDialog() == DialogResult.OK) { Task.Factory.StartNew(() => { // We need to enlarge in advance before entering the network Bitmap resultImage = new Bitmap(_baseImage.Width * 2, _baseImage.Height * 2, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(resultImage); // use nearest neighbor for interpolation g.InterpolationMode = InterpolationMode.NearestNeighbor; // Enlarge and draw the image g.DrawImage(_baseImage, 0, 0, _baseImage.Width * 2, _baseImage.Height * 2); g.Dispose(); NdArray image = NdArrayConverter.Image2NdArray(resultImage); NdArray[] resultArray = nn.Predict(true, image); resultImage = NdArrayConverter.NdArray2Image(resultArray[0].GetSingleArray(0)); resultImage.Save(sfd.FileName); pictureBox1.Image = new Bitmap(resultImage); } ).ContinueWith(_ => { MessageBox.Show("After the exchange finished"); }); MessageBox.Show("The conversion process has started. \n Please wait for a while until \"conversion complete\" message is displayed \n * It will take a very long time (about 3 minutes with 64 x 64 images)"); } }
public static void Run() { const int learningCount = 10000; Real[][] trainData = { new Real[] { 0, 0 }, new Real[] { 1, 0 }, new Real[] { 0, 1 }, new Real[] { 1, 1 } }; Real[][] trainLabel = { new Real[] { 0 }, new Real[] { 1 }, new Real[] { 1 }, new Real[] { 0 } }; bool verbose = true; FunctionStack nn = new FunctionStack("Test1", new Linear(verbose, 2, 2, name: "l1 Linear"), new Sigmoid(name: "l1 Sigmoid"), new Linear(verbose, 2, 2, name: "l2 Linear")); nn.SetOptimizer(new MomentumSGD()); Info("Training..."); for (int i = 0; i < learningCount; i++) { for (int j = 0; j < trainData.Length; j++) { Trainer.Train(nn, trainData[j], trainLabel[j], new SoftmaxCrossEntropy()); } } Info("Test Start..."); foreach (Real[] input in trainData) { NdArray result = nn.Predict(true, input)?[0]; int resultIndex = Array.IndexOf(result?.Data, result.Data.Max()); Info($"{input[0]} xor {input[1]} = {resultIndex} {result}"); } Info("Saving Model..."); ModelIO.Save(nn, "test.nn"); Info("Loading Model..."); FunctionStack testnn = ModelIO.Load("test.nn"); Info(testnn.Describe()); Info("Test Start..."); foreach (Real[] input in trainData) { NdArray result = testnn?.Predict(true, input)?[0]; int resultIndex = Array.IndexOf(result?.Data, result?.Data.Max()); Info($"{input[0]} xor {input[1]} = {resultIndex} {result}"); } }
public static void Run() { //訓練回数 const int learningCount = 10000; //訓練データ Real[][] trainData = { new Real[] { 0, 0 }, new Real[] { 1, 0 }, new Real[] { 0, 1 }, new Real[] { 1, 1 } }; //訓練データラベル Real[][] trainLabel = { new Real[] { 0 }, new Real[] { 1 }, new Real[] { 1 }, new Real[] { 0 } }; //ネットワークの構成は FunctionStack に書き連ねる FunctionStack nn = new FunctionStack( new Linear(2, 2, name: "l1 Linear"), new Sigmoid(name: "l1 Sigmoid"), new Linear(2, 2, name: "l2 Linear") ); //optimizerを宣言 nn.SetOptimizer(new MomentumSGD()); //訓練ループ Console.WriteLine("Training..."); for (int i = 0; i < learningCount; i++) { for (int j = 0; j < trainData.Length; j++) { //訓練実行時にロス関数を記述 Trainer.Train(nn, trainData[j], trainLabel[j], new SoftmaxCrossEntropy()); } } //訓練結果を表示 Console.WriteLine("Test Start..."); foreach (Real[] input in trainData) { NdArray result = nn.Predict(input)[0]; int resultIndex = Array.IndexOf(result.Data, result.Data.Max()); Console.WriteLine(input[0] + " xor " + input[1] + " = " + resultIndex + " " + result); } //学習の終わったネットワークを保存 ModelIO.Save(nn, "test.nn"); //学習の終わったネットワークを読み込み Function testnn = ModelIO.Load("test.nn"); Console.WriteLine("Test Start..."); foreach (Real[] input in trainData) { NdArray result = testnn.Predict(input)[0]; int resultIndex = Array.IndexOf(result.Data, result.Data.Max()); Console.WriteLine(input[0] + " xor " + input[1] + " = " + resultIndex + " " + result); } }
public static void Main() { // platformIdは、OpenCL・GPUの導入の記事に書いてある方法でご確認ください // https://jinbeizame.hateblo.jp/entry/kelpnet_opencl_gpu Weaver.Initialize(ComputeDeviceTypes.Gpu, platformId: 1, deviceIndex: 0); // ネットからVGGの学習済みモデルをダウンロード string modelFilePath = InternetFileDownloader.Donwload(DOWNLOAD_URL, MODEL_FILE); // 学習済みモデルをFunctionのリストとして保存 List <Function> vgg16Net = CaffemodelDataLoader.ModelLoad(modelFilePath); // VGGの出力層とその活性化関数を削除 vgg16Net.RemoveAt(vgg16Net.Count() - 1); vgg16Net.RemoveAt(vgg16Net.Count() - 1); // VGGの各FunctionのgpuEnableをtrueに for (int i = 0; i < vgg16Net.Count - 1; i++) { // GPUに対応している層であれば、GPU対応へ if (vgg16Net[i] is Convolution2D || vgg16Net[i] is Linear || vgg16Net[i] is MaxPooling) { ((IParallelizable)vgg16Net[i]).SetGpuEnable(true); } } // VGGをリストからFunctionStackに変換 FunctionStack vgg = new FunctionStack(vgg16Net.ToArray()); // 層を圧縮 vgg.Compress(); // 新しく出力層とその活性化関数を用意 FunctionStack nn = new FunctionStack( new Linear(4096, 1, gpuEnable: true), new Sigmoid() ); // 最適化手法としてAdamをセット nn.SetOptimizer(new Adam()); Console.WriteLine("DataSet Loading..."); // 訓練・テストデータ用のNdArrayを用意 // データセットは以下のURLからダウンロードを行い、 // VGGTransfer /bin/Debug/Data にtrainフォルダを置いてください。 // https://www.kaggle.com/c/dogs-vs-cats/data NdArray[] trainData = new NdArray[TRAIN_DATA_LENGTH * 2]; NdArray[] trainLabel = new NdArray[TRAIN_DATA_LENGTH * 2]; NdArray[] testData = new NdArray[TEST_DATA_LENGTH * 2]; NdArray[] testLabel = new NdArray[TEST_DATA_LENGTH * 2]; for (int i = 0; i < TRAIN_DATA_LENGTH + TEST_DATA_LENGTH; i++) { // 犬・猫の画像読み込み Bitmap baseCatImage = new Bitmap("Data/train/cat." + i + ".jpg"); Bitmap baseDogImage = new Bitmap("Data/train/dog." + i + ".jpg"); // 変換後の画像を格納するBitmapを定義 Bitmap catImage = new Bitmap(224, 224, PixelFormat.Format24bppRgb); Bitmap dogImage = new Bitmap(224, 224, PixelFormat.Format24bppRgb); // Graphicsオブジェクトに変換 Graphics gCat = Graphics.FromImage(catImage); Graphics gDog = Graphics.FromImage(dogImage); // Graphicsオブジェクト(の中のcatImageに)baseImageを変換して描画 gCat.DrawImage(baseCatImage, 0, 0, 224, 224); gDog.DrawImage(baseDogImage, 0, 0, 224, 224); // Graphicsオブジェクトを破棄し、メモリを解放 gCat.Dispose(); gDog.Dispose(); // 訓練・テストデータにデータを格納 // 先にテストデータの枚数分テストデータに保存し、その後訓練データを保存する // 画素値の値域は0 ~ 255のため、255で割ることで0 ~ 1に正規化 if (i < TEST_DATA_LENGTH) { // ImageをNdArrayに変換したものをvggに入力し、出力した特徴量を入力データとして保存 testData[i * 2] = vgg.Predict(NdArrayConverter.Image2NdArray(catImage, false, true) / 255.0)[0]; testLabel[i * 2] = new NdArray(new Real[] { 0 }); testData[i * 2 + 1] = vgg.Predict(NdArrayConverter.Image2NdArray(dogImage, false, true) / 255.0)[0]; testLabel[i * 2 + 1] = new NdArray(new Real[] { 1 }); } else { trainData[(i - TEST_DATA_LENGTH) * 2] = vgg.Predict(NdArrayConverter.Image2NdArray(catImage, false, true) / 255.0)[0]; trainLabel[(i - TEST_DATA_LENGTH) * 2] = new NdArray(new Real[] { 0 }); //new Real [] { 0 }; trainData[(i - TEST_DATA_LENGTH) * 2] = vgg.Predict(NdArrayConverter.Image2NdArray(dogImage, false, true) / 255.0)[0]; trainLabel[(i - TEST_DATA_LENGTH) * 2] = new NdArray(new Real[] { 1 }); // = new Real [] { 1 }; } } Console.WriteLine("Training Start..."); // ミニバッチ用のNdArrayを定義 NdArray batchData = new NdArray(new[] { 4096 }, BATCH_SIZE); NdArray batchLabel = new NdArray(new[] { 1 }, BATCH_SIZE); // 誤差関数を定義(今回は二値分類なので二乗誤差関数(MSE)) LossFunction lossFunction = new MeanSquaredError(); // エポックを回す for (int epoch = 0; epoch < 10; epoch++) { // 1エポックで訓練データ // バッチサイズ の回数分学習 for (int step = 0; step < TRAIN_DATA_COUNT; step++) { // ミニバッチを用意 for (int i = 0; i < BATCH_SIZE; i++) { // 0 ~ 訓練データサイズ-1 の中からランダムで整数を取得 int index = Mother.Dice.Next(trainData.Length); // trainData(NdArray[])を、batchData(NdArray)の形にコピー Array.Copy(trainData[index].Data, 0, batchData.Data, i * batchData.Length, batchData.Length); batchLabel.Data[i] = trainLabel[index].Data[0]; } // 学習(順伝播、誤差の計算、逆伝播、更新) NdArray[] output = nn.Forward(batchData); Real loss = lossFunction.Evaluate(output, batchLabel); nn.Backward(output); nn.Update(); } // 認識率(accuracy)の計算 // テストデータの回数データを回す Real accuracy = 0; for (int i = 0; i < TEST_DATA_LENGTH * 2; i++) { NdArray[] output = nn.Predict(testData[i]); // 出力outputと正解の誤差が0.5以下(正解が0のときにoutput<0.5、正解が1のときにoutput>0.5) // の際に正確に認識したとする if (Math.Abs(output[0].Data[0] - trainLabel[i].Data[0]) < 0.5) { accuracy += 1; } accuracy /= TEST_DATA_LENGTH * 2.0; Console.WriteLine("Epoch:" + epoch + "accuracy:" + accuracy); } } }
public static void Run(VGGModel modelType) { OpenFileDialog ofd = new OpenFileDialog { Filter = "画像ファイル(*.jpg;*.png;*.gif;*.bmp)|*.jpg;*.png;*.gif;*.bmp|すべてのファイル(*.*)|*.*" }; if (ofd.ShowDialog() == DialogResult.OK) { int vggId = (int)modelType; Console.WriteLine("Model Loading."); string modelFilePath = InternetFileDownloader.Donwload(Urls[vggId], FileNames[vggId], Hashes[vggId]); List <Function <Real> > vggNet = OnnxmodelDataLoader.LoadNetWork <Real>(modelFilePath); string[] classList = File.ReadAllLines(CLASS_LIST_PATH); //GPUを初期化 for (int i = 0; i < vggNet.Count - 1; i++) { if (vggNet[i] is CPU.Convolution2D <Real> || vggNet[i] is CPU.Linear <Real> || vggNet[i] is CPU.MaxPooling2D <Real> ) { vggNet[i] = (Function <Real>)CLConverter.Convert(vggNet[i]); } } FunctionStack <Real> nn = new FunctionStack <Real>(vggNet.ToArray()); //層を圧縮 nn.Compress(); Console.WriteLine("Model Loading done."); do { //ネットワークへ入力する前に解像度を 224px x 224px x 3ch にしておく Bitmap baseImage = new Bitmap(ofd.FileName); Bitmap resultImage = new Bitmap(224, 224, PixelFormat.Format24bppRgb); Graphics g = Graphics.FromImage(resultImage); g.DrawImage(baseImage, 0, 0, 224, 224); g.Dispose(); Real[] mean = new Real[] { 0.485f, 0.456f, 0.406f }; Real[] std = new Real[] { 0.229f, 0.224f, 0.225f }; NdArray <Real> imageArray = BitmapConverter.Image2NdArray <Real>(resultImage); int dataSize = imageArray.Shape[1] * imageArray.Shape[2]; for (int ch = 0; ch < imageArray.Shape[0]; ch++) { for (int i = 0; i < dataSize; i++) { imageArray.Data[ch * dataSize + i] = (imageArray.Data[ch * dataSize + i] - mean[ch]) / std[ch]; } } Console.WriteLine("Start predict."); Stopwatch sw = Stopwatch.StartNew(); NdArray <Real> result = nn.Predict(imageArray)[0]; sw.Stop(); Console.WriteLine("Result Time : " + (sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L))).ToString("n0") + "μs"); int maxIndex = Array.IndexOf(result.Data, result.Data.Max()); Console.WriteLine("[" + result.Data[maxIndex] + "] : " + classList[maxIndex]); } while (ofd.ShowDialog() == DialogResult.OK); } }
public static void Run() { const int learningCount = 10000; Real[][] trainData = { new Real[] { 0, 0 }, new Real[] { 1, 0 }, new Real[] { 0, 1 }, new Real[] { 1, 1 } }; //Training data label Real[][] trainLabel = { new Real[] { 0 }, new Real[] { 1 }, new Real[] { 1 }, new Real[] { 0 } }; //Network configuration is written in FunctionStack FunctionStack nn = new FunctionStack( new Linear(2, 2, name: "l1 Linear"), new Sigmoid(name: "l1 Sigmoid"), new Linear(2, 2, name: "l2 Linear") ); //optimizer nn.SetOptimizer(new MomentumSGD()); Console.WriteLine("Training..."); for (int i = 0; i < learningCount; i++) { for (int j = 0; j < trainData.Length; j++) { //Describe the loss function at training execution Trainer.Train(nn, trainData[j], trainLabel[j], new SoftmaxCrossEntropy()); } } //Show training results Console.WriteLine("Test Start..."); foreach (Real[] input in trainData) { NdArray result = nn.Predict(input)[0]; int resultIndex = Array.IndexOf(result.Data, result.Data.Max()); Console.WriteLine(input[0] + " xor " + input[1] + " = " + resultIndex + " " + result); } //Save network after learning ModelIO.Save(nn, "test.nn"); //Load the network after learning FunctionStack testnn = ModelIO.Load("test.nn"); Console.WriteLine("Test Start..."); foreach (Real[] input in trainData) { NdArray result = testnn.Predict(input)[0]; int resultIndex = Array.IndexOf(result.Data, result.Data.Max()); Console.WriteLine(input[0] + " xor " + input[1] + " = " + resultIndex + " " + result); } }