MultiTread application on Raspberry Pi with C# .NET 5.0
Continue with the Raspberry Pi work.
Deliverables
Temperature Reading
Read the temperature value form DS18B20 int a sub thread, this is because the temperature reading really cost some time.
Everytime it read the temperature value, send the value to the client with a TCP connection which the port Number is 1300(Mainely for sending messages).
PWM Adjustment
As I wish to make a PID controller, so ,To accomplish this goal, also need to adjust the PWM timely. I'm prepared to use Labview to control PWM with anothe port: 1200(Mainely for recieving messages).
As the two reason above, it's better to use multiple thread to implement the program.
ScreenShot
code
using System; using System.Net; using System.Net.Sockets; using System.Device.Gpio; using System.Device.Pwm.Drivers; using System.Threading; using System.Threading.Tasks; using Iot.Device.OneWire; using System.Text; using System.Collections.Generic; namespace ConsoleApp1 { class Program { static void Main(string[] args) { OneWireThermometerDevice theDs = null; GpioController controller = new GpioController(); //TCP connection define int PortTemperature = 1300; int PortPWM = 1200; IPAddress serverAddr = IPAddress.Parse("192.168.11.10"); TcpListener listenerTemp = null; TcpListener listenerPWM = null; NetworkStream streamTemp = null; NetworkStream streamPWM = null; string temperature = string.Empty; float pwm = 0; //PWM define int pin = 18; SoftwarePwmChannel theChannel = null; DeviceInitialize(ref theChannel, ref controller, pin, ref theDs); Console.WriteLine("Blinking LED. Press Ctrl+C to end."); #region TCP // Set the TcpListener on port 13000. Task.Run(() => ThreadReadTemperature()); // Enter the listening loop. while (true) { //pwm = float.Parse(Console.ReadLine()); //Console.Write(pwm); LEDSwitch(); } //// Shutdown and end connection //client.Close(); #endregion void ThreadReadTemperature() { try { while (true) { Byte[] sendBytes = null; Console.Write("Temperature Waiting for a connection... "); // TcpListener server = new TcpListener(port); listenerTemp = new TcpListener(serverAddr, PortTemperature); listenerTemp.Start(); // Perform a blocking call to accept requests. TcpClient client = listenerTemp.AcceptTcpClient(); Console.WriteLine("Temperature Connected!"); // Get a stream object for reading and writing streamTemp = client.GetStream(); // Loop to receive all the data sent by the client. // Start listening for client requests. while (true) { temperature = theDs.ReadTemperature().ToString(); sendBytes = Encoding.ASCII.GetBytes(temperature); streamTemp.Write(sendBytes, 0, sendBytes.Length); Console.WriteLine(temperature); } } } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); // Stop listening for new clients. listenerTemp.Stop(); } } void LEDSwitch() { try { Byte[] readBytes = new Byte[256]; Console.Write("PWM Waiting for a connection... "); // TcpListener server = new TcpListener(port); listenerPWM = new TcpListener(serverAddr, PortPWM); // Start listening for client requests. listenerPWM.Start(); // Perform a blocking call to accept requests. TcpClient client = listenerPWM.AcceptTcpClient(); Console.WriteLine("PWM Connected!"); // Get a stream object for reading and writing streamPWM = client.GetStream(); // Loop to receive all the data sent by the client. int i; while ((i = streamPWM.Read(readBytes, 0, readBytes.Length)) != 0) { pwm = float.Parse(Encoding.ASCII.GetString(readBytes)); Console.WriteLine($"PWM: {pwm}"); Console.WriteLine(temperature); if(0<=pwm && pwm<=1)theChannel.DutyCycle = pwm; //streamPWM.Flush(); } } catch (SocketException e) { Console.WriteLine("SocketException: {0}", e); // Stop listening for new clients. listenerPWM.Stop(); controller.ClosePin(pin); theChannel.Stop(); } //controller.Write(pin, ((ledOn) ? PinValue.High : PinValue.Low)); //ledOn = !ledOn; } void DeviceInitialize(ref SoftwarePwmChannel channel, ref GpioController theController, int ControlPin, ref OneWireThermometerDevice theDal) { string busID = "", devieID = ""; channel = new SoftwarePwmChannel(ControlPin, 400, 0.5, false, theController, false); channel.Start(); //theController.OpenPin(ControlPin, PinMode.Output); foreach (var device in OneWireThermometerDevice.EnumerateDevices()) { busID = device.BusId; devieID = device.DeviceId; Console.WriteLine(busID + "," + devieID + ","+device.Family); } theDal = new OneWireThermometerDevice(busID, devieID); } } } }
Read DS18B20 temperature with .NET 5.0 IoT throught TCP on Raspberry Pi 3B+
These days I was thinking about to make a PID controller use my Raspberry Pi Which has been layed in the trash corner for a long time.
At firsh I planned to do it with Labview only,but I found it is kind of difficult to make it come true.Thought there is a strong LINX tool with which you can operate the GPIO of Raspberry Pi directly, it didn't offer the One-Wire sensor like DS18B20. And with unknow reason the LINX don't have the custom command for Raspberry Pi, so I have to abandent.
Fortunately, I found a good another way to do it.
That is .NET Window IoT.
Microsoft also creates some tutorials. You can use .net 5.0 operate the GPIO directly.
And the .NET IoT Libraries 1.3.0 has lots of libraries that is very convenient to use.
R1: 4.7K Ohm or 10K Ohm resistor
CODE:
using System;
using System.Net;
using System.Net.Sockets;
using System.Device.Gpio;
using System.Threading;
using Iot.Device.Pwm;
using Iot.Device.OneWire;
using System.Text;
namespace ConsoleApp1
{
class Program
{
static void Main(string args)
{
OneWireThermometerDevice theDs = null;
GpioController controller = new GpioController();
int pin=18;
bool ledOn = true;
Console.WriteLine("Blinking LED. Press Ctrl+C to end.");
TcpListener server = null;
DeviceInitialize(ref controller, pin, ref theDs);
#region TCP
try
{
// Set the TcpListener on port 13000.
int port = 1300;
IPAddress serverAddr = IPAddress.Parse("192.168.11.10");
// TcpListener server = new TcpListener(port);
server = new TcpListener(serverAddr, port);
// Start listening for client requests.
server.Start();
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
// Loop to receive all the data sent by the client.
while (true)
{
ReadTemperature(ref stream);
}
//// Shutdown and end connection
//client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
// Stop listening for new clients.
server.Stop();
}
#endregion
void ReadTemperature(ref NetworkStream networkStream)
{
var temperature = theDs.ReadTemperature().ToString();
Byte sendBytes = Encoding.ASCII.GetBytes(temperature);
networkStream.Write(sendBytes, 0, sendBytes.Length);
Console.WriteLine(temperature);
controller.Write(pin, *1;
ledOn = !ledOn;
}
void DeviceInitialize(ref GpioController theController, int ControlPin, ref OneWireThermometerDevice theDal)
{
string busID = "", devieID = "";
theController.OpenPin(ControlPin, PinMode.Output);
foreach (var device in OneWireThermometerDevice.EnumerateDevices())
{
busID = device.BusId;
devieID = device.DeviceId;
Console.WriteLine(busID + "," + devieID + ","+device.Family);
}
theDal = new OneWireThermometerDevice(busID, devieID);
}
}
}
}
SCREENSHOOT:
left: recieved data right: sent data
*1:ledOn) ? PinValue.High : PinValue.Low
.net Framwork4.7.2 & VB.net でML.NETを試してみた(4)- トレニンーグモデルの再利用と実装
最近、Raspberry PiやLabveiwをやっていて、ML.NETのことを忘れていた。今日C#でRaspberryPi のTCP Service を作成するときにML.NETのことを思い出しました。
最近このようなを作成しました。
言語:VB.net フレームワーク:.net Framwork4.7.2 ML.NET:1.51
その他:AForge 2.2.5 カメラ撮影ライブラリー
機能:
- 選択されたフォルダ内のトレニンーグデータでトレニンーグモデル作成します。
- カメラで作成した画像を認識します。
- 選択された画像を認識します。
Imports AForge.Video.DirectShow
Imports Microsoft.ML
Imports Microsoft.ML.Data
Imports Microsoft.ML.DataOperationsCatalog
Imports Microsoft.ML.Vision
Imports Microsoft.ML.Transforms
Imports System.IO
Imports Tensorflow.Data
Imports System.Diagnostics.Eventing.Reader
Imports System.Drawing.Imaging
Public Class FrmDataTrain
#Region "Machine Learning"
Class ImageData
Public ImagePath As String
Public Label As String
End Class
Class ModelOutput
Public ImagePath As String
Public Label As String
Public PredictedLabel As String
End Class
Class ModelInput
Public Image() As Byte
Public LabelAsKey As UInt32
Public ImagePath As String
Public Label As String
'Public score As Double
End Class
Dim projectDirectory As String = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"))
Dim workspaceRelativePath As String = Path.Combine(projectDirectory, "workspace")
Public assetsRelativePath As String = Path.Combine(projectDirectory, "assets")
Dim theMLContext As MLContext = New MLContext()
Dim judgePicture As String
Dim testSet As IDataView
Dim images As IEnumerable(Of ImageData)
Dim theimageData As IDataView
Dim trainedModel As ITransformer
Dim predictionEngine As PredictionEngine(Of ModelInput, ModelOutput)
Dim modelSchema As DataViewSchema = Nothing
Public Iterator Function LoadImagesFromDirectory(ByVal folder As String, ByVal Optional useFolderNameAsLabel As Boolean = True) As IEnumerable(Of ImageData)
Dim files = Directory.GetFiles(folder, "*", SearchOption.AllDirectories)
For Each thefile In files
- If *1 Then
Continue For
Else
Dim theLabel = Path.GetFileName(thefile)
If useFolderNameAsLabel Then
theLabel = Directory.GetParent(thefile).Name
Else
For index = 0 To theLabel.Length
If (Not Char.IsLetter(theLabel(index))) Then
theLabel = theLabel.Substring(0, index)
Exit For
End If
Next
End If
Yield New ImageData With {.ImagePath = thefile, .Label = theLabel}
End If
Next
End Function
Private Sub TrainModel()
If TrainDataFolderBrowserDialog.SelectedPath <> Nothing Then
assetsRelativePath = TrainDataFolderBrowserDialog.SelectedPath
End If
images = LoadImagesFromDirectory(assetsRelativePath, True)
theimageData = theMLContext.Data.LoadFromEnumerable(images)
Dim shuffledData As IDataView = theMLContext.Data.ShuffleRows(theimageData)
Dim preprocessingPipeline As EstimatorChain(Of ImageLoadingTransformer) =
theMLContext.Transforms.Conversion.MapValueToKey("LabelAsKey", "Label").Append(
theMLContext.Transforms.LoadRawImageBytes("Image", assetsRelativePath, "ImagePath"))
Dim preProcessedData As IDataView = preprocessingPipeline.Fit(shuffledData).Transform(shuffledData)
Dim trainSplit As TrainTestData = theMLContext.Data.TrainTestSplit(preProcessedData, 0.3)
Dim validationTestSplit As TrainTestData = theMLContext.Data.TrainTestSplit(trainSplit.TestSet)
Dim trainSet As IDataView = trainSplit.TrainSet
Dim validationSet As IDataView = validationTestSplit.TrainSet
testSet = validationTestSplit.TestSet
Dim classifierOptions As ImageClassificationTrainer.Options = New ImageClassificationTrainer.Options With {
.FeatureColumnName = "Image",
.LabelColumnName = "LabelAsKey",
.ValidationSet = validationSet,
.Arch = ImageClassificationTrainer.Architecture.ResnetV2101,
.TestOnTrainSet = False,
.ReuseTrainSetBottleneckCachedValues = True,
.ReuseValidationSetBottleneckCachedValues = True,
.WorkspacePath = workspaceRelativePath
}
Dim trainingPipeline As EstimatorChain(Of KeyToValueMappingTransformer) = theMLContext.MulticlassClassification.Trainers.
ImageClassification(classifierOptions).Append(
theMLContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"))
trainedModel = trainingPipeline.Fit(trainSet)
theMLContext.Model.Save(trainedModel, theimageData.Schema, "model.zip")
End Sub
Private Sub OutputPrediction(ByVal prediction As ModelOutput)
Dim imageName As String = Path.GetFileName(prediction.ImagePath)
Console.WriteLine($"Image: {imageName} | Actual Value: {prediction.Label} | Predicted Value: {prediction.PredictedLabel}")
Debug.WriteLine($"Image: {imageName} | Actual Value: {prediction.Label} | Predicted Value: {prediction.PredictedLabel}")
End Sub
'一枚画像を認識する
Public Function ClassifySingleImage(ByVal Image As ModelInput, Optional ByRef accqurace As Double = 0.2) As String
Dim prediction As ModelOutput = predictionEngine.Predict(Image)
OutputPrediction(prediction)
Return prediction.PredictedLabel
End Function
#End Region
Dim _videoSource As VideoCaptureDevice = Nothing
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles OpenCameraButton.Click
'ビデオ入力デバイスのみ取得
Dim videoDevices = New FilterInfoCollection(FilterCategory.VideoInputDevice)
If videoDevices.Count = 0 Then 'ビデオデバイスが無い
Return
End If
Dim MonikerString = videoDevices(0).MonikerString '最初のビデオデバイスを使用
_videoSource = New VideoCaptureDevice(MonikerString)
'AddHandler _videoSource.NewFrame, AddressOf Me.Video_NewFrame
VideoSourcePlayer1.VideoSource = _videoSource
_videoSource.Start()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles StopCameraButton.Click
CloseCamera()
End Sub
'Private Sub Video_NewFrame(sender As Object, eventArgs As NewFrameEventArgs)
' VideoSourcePlayer1.VideoSource = _videoSource
' Dim img = DirectCast(eventArgs.Frame.Clone(), Bitmap)
'End Sub
'スクリーンショットを取る
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles SnapshotButton.Click
Dim bitmappicture As Bitmap = VideoSourcePlayer1.GetCurrentVideoFrame()
Dim Name As String = System.DateTime.Now.ToString("yyyymmdd-HHMMss") & ".JPG"
bitmappicture.Save("pictures\\" & Name, ImageFormat.Jpeg)
ImageList1.Images.Add(bitmappicture)
With ListView1
.Items.Add(Name)
.Items(.Items.Count - 1).ImageIndex = ImageList1.Images.Count - 1
End With
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
VideoSourcePlayer1.AutoSizeControl = False
Try
trainedModel = theMLContext.Model.Load("model.zip", modelSchema)
predictionEngine = theMLContext.Model.CreatePredictionEngine(Of ModelInput, ModelOutput)(trainedModel)
Catch ex As Exception
Debug.Print(ex.ToString())
End Try
End Sub
'トレニンーグに使用する写真データのフォルダを参照しする
Private Sub SelectFolderButton_Click(sender As Object, e As EventArgs) Handles SelectFolderButton.Click
TrainDataFolderBrowserDialog.ShowDialog()
Try
If TrainDataFolderBrowserDialog.SelectedPath <> Nothing Then
assetsRelativePath = TrainDataFolderBrowserDialog.SelectedPath
ComboBox1.Items.Insert(0, assetsRelativePath)
ComboBox1.SelectedItem = ComboBox1.Items.Item(0)
End If
Catch
End Try
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
CloseCamera()
End Sub
Sub CloseCamera()
If _videoSource Is Nothing Then
Return
End If
If _videoSource.IsRunning Then
_videoSource.SignalToStop() 'ビデオデバイスの停止
_videoSource.WaitForStop() '完全に停止するまで待つ
_videoSource = Nothing
End If
End Sub
'写真を選択する
Private Sub SelectFileButton_Click(sender As Object, e As EventArgs) Handles SelectFileButton.Click
If (PictureOpenFileDialog.ShowDialog() = DialogResult.OK) Then
judgePicture = PictureOpenFileDialog.FileName
End If
End Sub
'選択した写真を認識する
Private Sub JudgeButton_Click(sender As Object, e As EventArgs) Handles JudgeButton.Click
Dim thePicture As ImageData = New ImageData()
If ListView1.SelectedItems.Count <> 1 And judgePicture = Nothing Then
MessageBox.Show("写真一枚を選択してください")
Else
If ListView1.SelectedItems.Count = 1 Then
judgePicture = Application.StartupPath & "\pictures\" & ListView1.SelectedItems.Item(0).Text
With thePicture
.ImagePath = judgePicture
.Label = "Test"
End With
Else
With thePicture
.ImagePath = judgePicture
.Label = Path.GetFileName(Path.GetDirectoryName(judgePicture))
End With
End If
Dim theImages As IEnumerable(Of ImageData) = Enumerable.Empty(Of ImageData)
theImages = Enumerable.Append(theImages, thePicture)
'Dim Image As ModelInput = theMLContext.Data.CreateEnumerable(Of ModelInput)(testSet, True).First()
Dim testInputIDataView As IDataView = theMLContext.Data.LoadFromEnumerable(theImages)
Dim testInput As ModelInput
Dim PredictPreprocessingPipeline As EstimatorChain(Of ImageLoadingTransformer) =
theMLContext.Transforms.Conversion.MapValueToKey("LabelAsKey", "Label").Append(
theMLContext.Transforms.LoadRawImageBytes("Image", Nothing, "ImagePath"))
Dim unused As IDataView = PredictPreprocessingPipeline.Fit(testInputIDataView).Transform(testInputIDataView)
testInput = theMLContext.Data.CreateEnumerable(Of ModelInput)(unused, True).First()
Label2.Text = ClassifySingleImage(testInput)
End If
End Sub
'保存したモデルを削除し、再トレニンーグする
Private Sub TrainButton_Click(sender As Object, e As EventArgs) Handles TrainButton.Click
File.Delete("model.zip")
TrainModel()
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
If ComboBox1.SelectedItem.ToString <> Nothing Then
judgePicture = ComboBox1.SelectedItem.ToString
End If
End Sub
Private Sub BtRetrain_Click(sender As Object, e As EventArgs) Handles BtRetrain.Click
End Sub
End Class
.net Framwork4.7.2 & VB.net でML.NETを試してみた(3)- モデルのトレーニングと画像認識
ML.NETの転移学習のチュートリアルを参照して、VB.NETで実装してみます。
データの準備
前回の続き、プロジェクトの直下にフォルダ「assets」、「workspace」を作成し、以下のサイトからダウンロードしたデータを解凍し、「CD」、「UD」フォルダを「assets」にコピーする。
「assets」:トレーニングデータ
「workspace」:トレーニングモデルのデータなど
SDNET2018 is an image dataset that contains annotations for cracked and non-cracked concrete structures (bridge decks, walls, and pavement).
The data is organized in three subdirectories:
- D contains bridge deck images
- P contains pavement images
- W contains wall images
Each of these subdirectories contains two additional prefixed subdirectories:
- C is the prefix used for cracked surfaces
- U is the prefix used for uncracked surfaces
In this sample, only bridge deck images are used.
ダブルクリックコピペ
Formをダブルクリック、記事最後に載っているコードを作成しました。詳細はML.NETの転移学習のチュートリアルを参照して、より詳しい解説が載っています。
早速実行して見ると、ビルドできませんでした。
これはCPUターゲットを間違えたためです。x64のCPUターゲットを作成し、もう一回実行する。
問題なく動いています。
出力のところに結構スレッド何とか終了しましたなどがあるが、それはトレーニングを加速するためにマルチスレッドを使っていると思います。
モデルを訓練するため、2、3分ぐらいかかります。
予測は時々NG
トレーニング時間が足らないかもしれません。また調べてみます。
トレーニングモデルができたみたいですが、毎回のトレーニングすると大変です。
次回、モデルの保存、読み込むなどをやってみます。
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.IO
Imports Microsoft.ML
Imports Microsoft.ML.Data
Imports Microsoft.ML.DataOperationsCatalog
Imports Microsoft.ML.Vision
Imports Microsoft.ML.Transforms
Imports Tensorflow.Data
Public Class Form1
#Region "Machine Learning"
'画像データクラス
Class ImageData
Public ImagePath As String
Public Label As String
End Class
'入力データクラス
Class ModelInput
Public Image() As Byte
Public LabelAsKey As UInt32
Public ImagePath As String
Public Label As String
'Public score As Double
End Class
'出力データクラス
Class ModelOutput
Public ImagePath As String
Public Label As String
Public PredictedLabel As String
End Class
'ワークスペース ディレクトリを作成する
Dim projectDirectory As String = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "../../../"))
Dim workspaceRelativePath As String = Path.Combine(projectDirectory, "workspace")
Public assetsRelativePath As String = Path.Combine(projectDirectory, "assets")
Dim theMLContext As MLContext = New MLContext()
Dim judgePicture As String
Dim testSet As IDataView
Dim images As IEnumerable(Of ImageData)
Dim theimageData As IDataView
Dim trainedModel As ITransformer
Dim predictionEngine As PredictionEngine(Of ModelInput, ModelOutput)
Dim modelSchema As DataViewSchema = Nothing
'データ読み込みユーティリティ メソッドを作成する
Public Iterator Function LoadImagesFromDirectory(ByVal folder As String, ByVal Optional useFolderNameAsLabel As Boolean = True) As IEnumerable(Of ImageData)
Dim files = Directory.GetFiles(folder, "*", SearchOption.AllDirectories)
For Each thefile In files
If *1 Then
Continue For
Else
Dim theLabel = Path.GetFileName(thefile)
If useFolderNameAsLabel Then
theLabel = Directory.GetParent(thefile).Name
Else
For index = 0 To theLabel.Length
If (Not Char.IsLetter(theLabel(index))) Then
theLabel = theLabel.Substring(0, index)
Exit For
End If
Next
End If
Yield New ImageData With {.ImagePath = thefile, .Label = theLabel}
End If
Next
End Function
'モデルを使用する
Private Sub OutputPrediction(ByVal prediction As ModelOutput)
Dim imageName As String = Path.GetFileName(prediction.ImagePath)
Console.WriteLine($"Image: {imageName} | Actual Value: {prediction.Label} | Predicted Value: {prediction.PredictedLabel}")
Debug.WriteLine($"Image: {imageName} | Actual Value: {prediction.Label} | Predicted Value: {prediction.PredictedLabel}")
End Sub
'1 枚の画像を分類する
Public Sub ClassifySingleImage(ByVal themlContext As MLContext, ByVal data As IDataView, ByVal trainModel As ITransformer)
Dim predictionEngine As PredictionEngine(Of ModelInput, ModelOutput) = themlContext.Model.CreatePredictionEngine(Of ModelInput, ModelOutput)(trainedModel)
Dim image As ModelInput = themlContext.Data.CreateEnumerable(Of ModelInput)(data, True).First()
Dim prediction As ModelOutput = predictionEngine.Predict(image)
Console.WriteLine("Classifying single image")
OutputPrediction(prediction)
End Sub
#End Region
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'データを準備する
images = LoadImagesFromDirectory(assetsRelativePath, True)
theimageData = theMLContext.Data.LoadFromEnumerable(images)
Dim shuffledData As IDataView = theMLContext.Data.ShuffleRows(theimageData)
Dim preprocessingPipeline As EstimatorChain(Of ImageLoadingTransformer) =
theMLContext.Transforms.Conversion.MapValueToKey("LabelAsKey", "Label").Append(
theMLContext.Transforms.LoadRawImageBytes("Image", assetsRelativePath, "ImagePath"))
Dim preProcessedData As IDataView = preprocessingPipeline.Fit(shuffledData).Transform(shuffledData)
Dim trainSplit As TrainTestData = theMLContext.Data.TrainTestSplit(preProcessedData, 0.3)
Dim validationTestSplit As TrainTestData = theMLContext.Data.TrainTestSplit(trainSplit.TestSet)
Dim trainSet As IDataView = trainSplit.TrainSet
Dim validationSet As IDataView = validationTestSplit.TrainSet
testSet = validationTestSplit.TestSet
'トレーニング パイプラインを定義する
Dim classifierOptions As ImageClassificationTrainer.Options = New ImageClassificationTrainer.Options With {
.FeatureColumnName = "Image",
.LabelColumnName = "LabelAsKey",
.ValidationSet = validationSet,
.Arch = ImageClassificationTrainer.Architecture.ResnetV2101,
.TestOnTrainSet = False,
.ReuseTrainSetBottleneckCachedValues = True,
.ReuseValidationSetBottleneckCachedValues = True,
.WorkspacePath = workspaceRelativePath
}
Dim trainingPipeline As EstimatorChain(Of KeyToValueMappingTransformer) = theMLContext.MulticlassClassification.Trainers.ImageClassification(classifierOptions).Append(theMLContext.Transforms.Conversion.MapKeyToValue("PredictedLabel"))
trainedModel = trainingPipeline.Fit(trainSet)
'画像のテスト セットを利用して ClassifySingleImage を呼び出します
ClassifySingleImage(theMLContext, testSet, trainedModel)
End Sub
End Class
.net Framwork4.7.2 & VB.net でML.NETを試してみた(2)- プロジェクト作成とパッケージのインストール
ML.NETを導入する時は便利なツールがあります。それはML.NET Model Builderです。
クリックだけで、train modelを作れる、コードまで自動的に生成する。
ただ、VB.NETがサポートされていないです。そこで、ML.NETのAPIを使って画像認識を行います。
プロジェクトの作成とパッケージのインストール
今回は転移学習のチュートリアルを参照して、VB.netに書き換えてみます。
プロジェクトの作成は結構簡単です。
転移学習
簡単に言うとTensorflowですでにトレーニングしたモデルを用いて、自分のデータと合わせてトレーニングし、モデルを特化する学習するプログレスです。
利点としては、モデルの学習時間が短縮できます。
欠点は、事前トレーニング済みモデルなので、不要データが入っているので、データが大きい。
.net Framwork4.7.2 & VB.net でML.NETを試してみた(1)- 実行環境の紹介
最近ML.NETを使ってみました。ネット上検索してみたら、たくさん紹介記事が出てくると思いますが、基本C#コードのMicrosoftのチュートリアルの紹介です。
私の会社では基本VBは主なる言語で、VB.NETとC#が似てると言っても、VBをC#に変えることがなかなかできなそもないです。
そこで、ML.NETがVB.NETで使えるかどうかを調べました。
ML.NETの実行環境
Microsoftの紹介ページによると、ML.NETがC#、F#をサポートしています。
また、チュートリアルのサンプルプロジェクトは .NET Coreでないとダメ見たいです。
しかし、ML. NETのGitHubページを見ると .NET Frameworkもサポートされています。
さらに、気になった画像認識の機能使えるかどうかを質問したところ、OKの返事も来ました。
屋内ARナビ Indoor AR navigation
図書館ARナビゲーション
#Unity #AR #ARkit
— 李奇傑 (@EijiiQ) 2019年9月20日
Indoor AR navigation for library 😄 pic.twitter.com/GBapCIyUmb