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() { 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 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); } }
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 MnistDataLoader() { string trainlabelPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TRAIN_LABEL, TRAIN_LABEL, TRAIN_LABEL_HASH); MnistLabelLoader trainLabelLoader = MnistLabelLoader.Load(trainlabelPath); this.TrainLabel = trainLabelLoader.labelList; string trainimagePath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TRAIN_IMAGE, TRAIN_IMAGE, TRAIN_IMAGE_HASH); MnistImageLoader trainImageLoader = MnistImageLoader.Load(trainimagePath); this.TrainData = trainImageLoader.bitmapList.ToArray(); string teachlabelPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TEACH_LABEL, TEACH_LABEL, TEACH_LABEL_HASH); MnistLabelLoader teachLabelLoader = MnistLabelLoader.Load(teachlabelPath); this.TeachLabel = teachLabelLoader.labelList; string teachimagePath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TEACH_IMAGE, TEACH_IMAGE, TEACH_IMAGE_HASH); MnistImageLoader teachImageLoader = MnistImageLoader.Load(teachimagePath); this.TeachData = teachImageLoader.bitmapList.ToArray(); }
public FashionMnistDataLoader() { //ファイル名がMNISTと同じ為、保存名は"fashion-"を足している string trainlabelPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TRAIN_LABEL, "fashion-" + TRAIN_LABEL, TRAIN_LABEL_HASH); MnistLabelLoader trainLabelLoader = MnistLabelLoader.Load(trainlabelPath); this.TrainLabel = trainLabelLoader.labelList; string trainimagePath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TRAIN_IMAGE, "fashion-" + TRAIN_IMAGE, TRAIN_IMAGE_HASH); MnistImageLoader trainImageLoader = MnistImageLoader.Load(trainimagePath); this.TrainData = trainImageLoader.bitmapList.ToArray(); string teachlabelPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TEACH_LABEL, "fashion-" + TEACH_LABEL, TEACH_LABEL_HASH); MnistLabelLoader teachLabelLoader = MnistLabelLoader.Load(teachlabelPath); this.TeachLabel = teachLabelLoader.labelList; string teachimagePath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TEACH_IMAGE, "fashion-" + TEACH_IMAGE, TEACH_IMAGE_HASH); MnistImageLoader teachImageLoader = MnistImageLoader.Load(teachimagePath); this.TeachData = teachImageLoader.bitmapList.ToArray(); }
public static void Run() { Console.WriteLine("Build Vocabulary."); Vocabulary vocabulary = new Vocabulary(); string trainPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TRAIN_FILE, TRAIN_FILE, TRAIN_FILE_HASH); string testPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TEST_FILE, TEST_FILE, TEST_FILE_HASH); int[] trainData = vocabulary.LoadData(trainPath); int[] testData = vocabulary.LoadData(testPath); int nVocab = vocabulary.Length; Console.WriteLine("Done."); Console.WriteLine("Network Initilizing."); FunctionStack model = new FunctionStack( new EmbedID(nVocab, N_UNITS, name: "l1 EmbedID"), new Linear(N_UNITS, N_UNITS, name: "l2 Linear"), new TanhActivation("l2 Tanh"), new Linear(N_UNITS, nVocab, name: "l3 Linear"), new Softmax("l3 Sonftmax") ); model.SetOptimizer(new Adam()); List <int> s = new List <int>(); Console.WriteLine("Train Start."); SoftmaxCrossEntropy softmaxCrossEntropy = new SoftmaxCrossEntropy(); for (int epoch = 0; epoch < TRAINING_EPOCHS; epoch++) { for (int pos = 0; pos < trainData.Length; pos++) { NdArray h = new NdArray(new Real[N_UNITS]); int id = trainData[pos]; s.Add(id); if (id == vocabulary.EosID) { Real accumloss = 0; Stack <NdArray> tmp = new Stack <NdArray>(); for (int i = 0; i < s.Count; i++) { int tx = i == s.Count - 1 ? vocabulary.EosID : s[i + 1]; //l1 EmbedID NdArray l1 = model.Functions[0].Forward(s[i])[0]; //l2 Linear NdArray l2 = model.Functions[1].Forward(h)[0]; //Add NdArray xK = l1 + l2; //l2 Tanh h = model.Functions[2].Forward(xK)[0]; //l3 Linear NdArray h2 = model.Functions[3].Forward(h)[0]; Real loss = softmaxCrossEntropy.Evaluate(h2, tx); tmp.Push(h2); accumloss += loss; } Console.WriteLine(accumloss); for (int i = 0; i < s.Count; i++) { model.Backward(tmp.Pop()); } model.Update(); s.Clear(); } if (pos % 100 == 0) { Console.WriteLine(pos + "/" + trainData.Length + " finished"); } } } Console.WriteLine("Test Start."); Real sum = 0; int wnum = 0; List <int> ts = new List <int>(); bool unkWord = false; for (int pos = 0; pos < 1000; pos++) { int id = testData[pos]; ts.Add(id); if (id > trainData.Length) { unkWord = true; } if (id == vocabulary.EosID) { if (!unkWord) { Console.WriteLine("pos" + pos); Console.WriteLine("tsLen" + ts.Count); Console.WriteLine("sum" + sum); Console.WriteLine("wnum" + wnum); sum += CalPs(model, ts); wnum += ts.Count - 1; } else { unkWord = false; } ts.Clear(); } } Console.WriteLine(Math.Pow(2.0, sum / wnum)); }
public CIFARDataLoader(bool isCifar100 = false) { if (!isCifar100) { string cifar10Path = InternetFileDownloader.Donwload(DOWNLOAD_URL + CIFAR10, CIFAR10); Dictionary<string, byte[]> data = Tar.GetExtractedStreams(cifar10Path); this.LabelNames = Encoding.ASCII.GetString(data["cifar-10-batches-bin/batches.meta.txt"]).Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries); List<byte> trainLabel = new List<byte>(); List<byte[]> trainData = new List<byte[]>(); for (int i = 0; i < CIFAR10TrainNames.Length; i++) { for (int j = 0; j < CIFAR10_DATA_COUNT; j++) { trainLabel.Add(data[CIFAR10TrainNames[i]][j * (DATA_SIZE + LABEL_SIZE)]); byte[] tmpArray = new byte[DATA_SIZE]; Array.Copy(data[CIFAR10TrainNames[i]], j * (DATA_SIZE + LABEL_SIZE) + LABEL_SIZE, tmpArray, 0, tmpArray.Length); trainData.Add(tmpArray); } } this.TrainLabel = trainLabel.ToArray(); this.TrainData = trainData.ToArray(); List<byte> testLabel = new List<byte>(); List<byte[]> testData = new List<byte[]>(); for (int j = 0; j < CIFAR10_DATA_COUNT; j++) { testLabel.Add(data[CIFAR10TestName][j * (DATA_SIZE + LABEL_SIZE)]); byte[] tmpArray = new byte[DATA_SIZE]; Array.Copy(data[CIFAR10TestName], j * (DATA_SIZE + LABEL_SIZE) + LABEL_SIZE, tmpArray, 0, tmpArray.Length); testData.Add(tmpArray); } this.TestLabel = testLabel.ToArray(); this.TestData = testData.ToArray(); } else { string cifar100Path = InternetFileDownloader.Donwload(DOWNLOAD_URL + CIFAR100, CIFAR100); Dictionary<string, byte[]> data = Tar.GetExtractedStreams(cifar100Path); //簡素なラベル名称 this.LabelNames = Encoding.ASCII.GetString(data["cifar-100-binary/coarse_label_names.txt"]).Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); //詳細なラベル名称 this.FineLabelNames = Encoding.ASCII.GetString(data["cifar-100-binary/fine_label_names.txt"]).Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries); List<byte> trainLabel = new List<byte>(); List<byte> trainFineLabel = new List<byte>(); List<byte[]> trainData = new List<byte[]>(); for (int j = 0; j < CIFAR100_DATA_COUNT; j++) { trainLabel.Add(data[CIFAR100TrainName][j * (DATA_SIZE + LABEL_SIZE + LABEL_SIZE)]); trainFineLabel.Add(data[CIFAR100TrainName][j * (DATA_SIZE + LABEL_SIZE + LABEL_SIZE) + LABEL_SIZE]); byte[] tmpArray = new byte[DATA_SIZE]; Array.Copy(data[CIFAR100TrainName], j * (DATA_SIZE + LABEL_SIZE + LABEL_SIZE) + LABEL_SIZE + LABEL_SIZE, tmpArray, 0, tmpArray.Length); trainData.Add(tmpArray); } this.TrainLabel = trainLabel.ToArray(); this.TrainFineLabel = trainFineLabel.ToArray(); this.TrainData = trainData.ToArray(); List<byte> testLabel = new List<byte>(); List<byte> testFineLabel = new List<byte>(); List<byte[]> testData = new List<byte[]>(); for (int j = 0; j < CIFAR100_TEST_DATA_COUNT; j++) { testLabel.Add(data[CIFAR100TestName][j * (DATA_SIZE + LABEL_SIZE + LABEL_SIZE)]); testFineLabel.Add(data[CIFAR100TestName][j * (DATA_SIZE + LABEL_SIZE + LABEL_SIZE) + LABEL_SIZE]); byte[] tmpArray = new byte[DATA_SIZE]; Array.Copy(data[CIFAR100TestName], j * (DATA_SIZE + LABEL_SIZE + LABEL_SIZE) + LABEL_SIZE + LABEL_SIZE, tmpArray, 0, tmpArray.Length); testData.Add(tmpArray); } this.TestLabel = testLabel.ToArray(); this.TestFineLabel = testFineLabel.ToArray(); this.TestData = testData.ToArray(); } }
public static void Run() { Console.WriteLine("Build Vocabulary."); Vocabulary vocabulary = new Vocabulary(); string trainPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TRAIN_FILE, TRAIN_FILE); string validPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + VALID_FILE, VALID_FILE); string testPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TEST_FILE, TEST_FILE); int[] trainData = vocabulary.LoadData(trainPath); int[] validData = vocabulary.LoadData(validPath); int[] testData = vocabulary.LoadData(testPath); int nVocab = vocabulary.Length; Console.WriteLine("Network Initilizing."); FunctionStack model = new FunctionStack( new EmbedID(nVocab, N_UNITS, name: "l1 EmbedID"), new Dropout(), new LSTM(N_UNITS, N_UNITS, name: "l2 LSTM"), new Dropout(), new LSTM(N_UNITS, N_UNITS, name: "l3 LSTM"), new Dropout(), new Linear(N_UNITS, nVocab, name: "l4 Linear") ); //与えられたthresholdで頭打ちではなく、全パラメータのL2Normからレートを取り補正を行う GradientClipping gradientClipping = new GradientClipping(threshold: GRAD_CLIP); SGD sgd = new SGD(learningRate: 1); model.SetOptimizer(gradientClipping, sgd); Real wholeLen = trainData.Length; int jump = (int)Math.Floor(wholeLen / BATCH_SIZE); int epoch = 0; Stack <NdArray[]> backNdArrays = new Stack <NdArray[]>(); Console.WriteLine("Train Start."); for (int i = 0; i < jump * N_EPOCH; i++) { NdArray x = new NdArray(new[] { 1 }, BATCH_SIZE); NdArray t = new NdArray(new[] { 1 }, BATCH_SIZE); for (int j = 0; j < BATCH_SIZE; j++) { x.Data[j] = trainData[(int)((jump * j + i) % wholeLen)]; t.Data[j] = trainData[(int)((jump * j + i + 1) % wholeLen)]; } NdArray[] result = model.Forward(x); Real sumLoss = new SoftmaxCrossEntropy().Evaluate(result, t); backNdArrays.Push(result); Console.WriteLine("[{0}/{1}] Loss: {2}", i + 1, jump, sumLoss); //Run truncated BPTT if ((i + 1) % BPROP_LEN == 0) { for (int j = 0; backNdArrays.Count > 0; j++) { Console.WriteLine("backward" + backNdArrays.Count); model.Backward(backNdArrays.Pop()); } model.Update(); model.ResetState(); } if ((i + 1) % jump == 0) { epoch++; Console.WriteLine("evaluate"); Console.WriteLine("validation perplexity: {0}", Evaluate(model, validData)); if (epoch >= 6) { sgd.LearningRate /= 1.2; Console.WriteLine("learning rate =" + sgd.LearningRate); } } } Console.WriteLine("test start"); Console.WriteLine("test perplexity:" + Evaluate(model, testData)); }
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 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() { Console.WriteLine("Build Vocabulary."); Vocabulary vocabulary = new Vocabulary(); string trainPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TRAIN_FILE, TRAIN_FILE, TRAIN_FILE_HASH); string validPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + VALID_FILE, VALID_FILE, VALID_FILE_HASH); string testPath = InternetFileDownloader.Donwload(DOWNLOAD_URL + TEST_FILE, TEST_FILE, TEST_FILE_HASH); int[] trainData = vocabulary.LoadData(trainPath); int[] validData = vocabulary.LoadData(validPath); int[] testData = vocabulary.LoadData(testPath); int nVocab = vocabulary.Length; Console.WriteLine("Network Initilizing."); FunctionStack <Real> model = new FunctionStack <Real>( new EmbedID <Real>(nVocab, N_UNITS, name: "l1 EmbedID"), new Dropout <Real>(), new LSTM <Real>(N_UNITS, N_UNITS, name: "l2 LSTM"), new Dropout <Real>(), new LSTM <Real>(N_UNITS, N_UNITS, name: "l3 LSTM"), new Dropout <Real>(), new Linear <Real>(N_UNITS, nVocab, name: "l4 Linear") ); for (int i = 0; i < model.Functions.Length; i++) { for (int j = 0; j < model.Functions[i].Parameters.Length; j++) { for (int k = 0; k < model.Functions[i].Parameters[j].Data.Length; k++) { model.Functions[i].Parameters[j].Data[k] = ((Real)Mother.Dice.NextDouble() * 2.0f - 1.0f) / 10.0f; } } } //与えられたthresholdで頭打ちではなく、全パラメータのL2Normからレートを取り補正を行う GradientClipping <Real> gradientClipping = new GradientClipping <Real>(threshold: GRAD_CLIP); SGD <Real> sgd = new SGD <Real>(learningRate: 0.1f); gradientClipping.SetUp(model); sgd.SetUp(model); Real wholeLen = trainData.Length; int jump = (int)Math.Floor(wholeLen / BATCH_SIZE); int epoch = 0; Console.WriteLine("Train Start."); for (int i = 0; i < jump * N_EPOCH; i++) { NdArray <Real> x = new NdArray <Real>(new[] { 1 }, BATCH_SIZE); NdArray <int> t = new NdArray <int>(new[] { 1 }, BATCH_SIZE); for (int j = 0; j < BATCH_SIZE; j++) { x.Data[j] = trainData[(int)((jump * j + i) % wholeLen)]; t.Data[j] = trainData[(int)((jump * j + i + 1) % wholeLen)]; } NdArray <Real> result = model.Forward(x)[0]; Real sumLoss = new SoftmaxCrossEntropy <Real>().Evaluate(result, t); Console.WriteLine("[{0}/{1}] Loss: {2}", i + 1, jump, sumLoss); model.Backward(result); //Run truncated BPTT if ((i + 1) % BPROP_LEN == 0) { gradientClipping.Update(); sgd.Update(); model.ResetState(); } if ((i + 1) % jump == 0) { epoch++; Console.WriteLine("evaluate"); Console.WriteLine("validation perplexity: {0}", Evaluate(model, validData)); if (epoch >= 6) { sgd.LearningRate /= 1.2f; Console.WriteLine("learning rate =" + sgd.LearningRate); } } } Console.WriteLine("test start"); Console.WriteLine("test perplexity:" + Evaluate(model, testData)); }