private void timer1_Tick(object sender, EventArgs e) { //移植元では同じ教育画像で教育しているが、より実践に近い学習に変更 if (counter < 11) { //ランダムに点が打たれた画像を生成 NdArray img_p = getRandomImage(); //目標とするフィルタで学習用の画像を出力 NdArray[] img_core = decon_core.Forward(img_p); //未学習のフィルタで画像を出力 NdArray[] img_y = model.Forward(img_p); //img_yを暗黙的にNdArrayとして使用 BackgroundImage = NdArrayConverter.NdArray2Image(img_y[0].GetSingleArray(0)); Real loss = meanSquaredError.Evaluate(img_y, img_core); model.Backward(img_y); model.Update(); Text = "[epoch" + counter + "] Loss : " + string.Format("{0:F4}", loss); counter++; } else { timer1.Enabled = false; } }
public static void Run() { //目標とするフィルタを作成(実践であればココは不明な値となる) Deconvolution2D decon_core = new Deconvolution2D(1, 1, 15, 1, 7, gpuEnable: true) { Weight = { Data = MakeOneCore() } }; Deconvolution2D model = new Deconvolution2D(1, 1, 15, 1, 7, gpuEnable: true); SGD optimizer = new SGD(learningRate: 0.00005); //大きいと発散する model.SetOptimizer(optimizer); MeanSquaredError meanSquaredError = new MeanSquaredError(); //移植元では同じ教育画像で教育しているが、より実践に近い学習に変更 for (int i = 0; i < 11; i++) { //ランダムに点が打たれた画像を生成 NdArray img_p = getRandomImage(); //目標とするフィルタで学習用の画像を出力 NdArray[] img_core = decon_core.Forward(img_p); //未学習のフィルタで画像を出力 NdArray[] img_y = model.Forward(img_p); Real loss = meanSquaredError.Evaluate(img_y, img_core); model.Backward(img_y); model.Update(); Console.WriteLine("epoch" + i + " : " + loss); } }
public static void Run() { //Create a target filter (If it is practical, here is an unknown value) Deconvolution2D decon_core = new Deconvolution2D(1, 1, 15, 1, 7, gpuEnable: true) { Weight = { Data = MakeOneCore() } }; Deconvolution2D model = new Deconvolution2D(1, 1, 15, 1, 7, gpuEnable: true); SGD optimizer = new SGD(learningRate: 0.00005); //When it is big, it diverges. model.SetOptimizer(optimizer); MeanSquaredError meanSquaredError = new MeanSquaredError(); //At the transplant source, we are educating with the same educational image, but changing to learning closer to practice for (int i = 0; i < 11; i++) { //Generate random dotted images NdArray img_p = getRandomImage(); //Output a learning image with a target filter NdArray[] img_core = decon_core.Forward(img_p); //Output an image with an unlearned filter NdArray[] img_y = model.Forward(img_p); Real loss = meanSquaredError.Evaluate(img_y, img_core); model.Backward(img_y); model.Update(); Console.WriteLine("epoch" + i + " : " + loss); } }
public static void Run() { // Create a target filter (In case of practice, here is the unknown value) Deconvolution2D decon_core = new Deconvolution2D(true, 1, 1, 15, 1, 7, gpuEnable: true) { Weight = { Data = MakeOneCore() } }; Deconvolution2D model = new Deconvolution2D(true, 1, 1, 15, 1, 7, gpuEnable: true); SGD optimizer = new SGD(learningRate: 0.00005); // diverge if big model.SetOptimizer(optimizer); MeanSquaredError meanSquaredError = new MeanSquaredError(); // I am educating with the same educational image at the transplanting source, but changing to learning closer to practice for (int i = 0; i < 11; i++) { // Generate an image with randomly struck points NdArray img_p = getRandomImage(); // Output a learning image with a target filter NdArray[] img_core = decon_core.Forward(true, img_p); // Output an image with an unlearned filter NdArray[] img_y = model.Forward(true, img_p); Real loss = meanSquaredError.Evaluate(img_y, img_core); model.Backward(true, img_y); model.Update(); RILogManager.Default?.SendDebug("epoch" + i + " : " + loss); } }
private void timer1_Tick(object sender, EventArgs e) { // I am educating with the same educational image at the transplanting source, but changing to learning closer to practice if (counter < 11) { // Generate an image with randomly struck points NdArray img_p = getRandomImage(); // Output a learning image with a target filter NdArray[] img_core = decon_core?.Forward(true, img_p); // Output an image with an unlearned filter NdArray[] img_y = model?.Forward(true, img_p); // implicitly use img_y as NdArray BackgroundImage = NdArrayConverter.NdArray2Image(img_y[0].GetSingleArray(0)); Real loss = meanSquaredError.Evaluate(img_y, img_core); model.Backward(true, img_y); model.Update(); Text = "[epoch" + counter + "] Loss : " + $"{loss:F4}"; counter++; } else { timer1.Enabled = false; } }
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); } } }