Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        public static void Run(ResnetModel modelType)
        {
            OpenFileDialog ofd = new OpenFileDialog {
                Filter = "画像ファイル(*.jpg;*.png;*.gif;*.bmp)|*.jpg;*.png;*.gif;*.bmp|すべてのファイル(*.*)|*.*"
            };

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                int resnetId = (int)modelType;

                Console.WriteLine("Mean Loading.");
                string  meanFilePath = InternetFileDownloader.Donwload(DOWNLOAD_URL_MEAN, MODEL_FILE_MEAN, MODEL_FILE_MEAN_HASH);
                NdArray mean         = CaffemodelDataLoader.ReadBinary(meanFilePath);

                Console.WriteLine("Model Loading.");
                string             modelFilePath = InternetFileDownloader.Donwload(Urls[resnetId], FileNames[resnetId], Hashes[resnetId]);
                FunctionDictionary nn            = CaffemodelDataLoader.LoadNetWork(modelFilePath);
                string[]           classList     = File.ReadAllLines(CLASS_LIST_PATH);

                //GPUを初期化
                foreach (FunctionStack resNetFunctionBlock in nn.FunctionBlocks)
                {
                    SwitchGPU(resNetFunctionBlock);
                }

                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.InterpolationMode = InterpolationMode.Bilinear;
                    g.DrawImage(baseImage, 0, 0, 224, 224);
                    g.Dispose();

                    NdArray imageArray = NdArrayConverter.Image2NdArray(resultImage, false, true);
                    imageArray           -= mean;
                    imageArray.ParentFunc = null;

                    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);
            }
        }
Ejemplo n.º 4
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 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);
            }
        }
    }