ChatGPT
2023/3 ChatGPTがとても元気ですね。いろいろな質問に答えてくれますが、時に適当(間違った(^^;)な回答をしてくれることもあるようです。とはいいつつ、プログラムを自動生成してくれたりしてとても便利です。ここではいくつかの実験をしてみます。
Arduinoプログラミング
Q. arduinoでledを2つ交互に点滅するプログラム
A. 以下は、Arduinoで2つのLEDを交互に点滅させるプログラムの例です。LEDの接続ピンは、自分が使用しているArduinoボードに応じて変更してください。
int ledPin1 = 2; // LED1の接続ピン
int ledPin2 = 3; // LED2の接続ピン
int delayTime = 500; // 点滅間隔(ミリ秒)
void setup() {
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
}
void loop() {
digitalWrite(ledPin1, HIGH); // LED1を点灯
digitalWrite(ledPin2, LOW); // LED2を消灯
delay(delayTime); // 点灯時間待機
digitalWrite(ledPin1, LOW); // LED1を消灯
digitalWrite(ledPin2, HIGH); // LED2を点灯
delay(delayTime); // 点灯時間待機
}
このプログラムでは、setup()関数でLEDピンを出力に設定し、loop()関数で2つのLEDを交互に点滅させています。digitalWrite()関数を使用して、LEDの状態をHIGHまたはLOWに設定し、delay()関数を使用して点灯時間を待機しています。
// 74HC595 ピン定義
const int latchPin = 8; // ラッチピン
const int clockPin = 12; // クロックピン
const int dataPin = 11; // データピン
void setup() {
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
for (int i = 0; i < 10; i++) {
shiftOut(dataPin, clockPin, MSBFIRST, 1 << i); // 1ビットだけシフトして、LEDを点灯
digitalWrite(latchPin, HIGH); // ラッチピンをHIGHに設定して、シフトレジスタの出力を更新
digitalWrite(latchPin, LOW); // ラッチピンをLOWに設定して、シフトレジスタの出力を固定
delay(100); // 100ミリ秒待機
shiftOut(dataPin, clockPin, MSBFIRST, 0); // 0ビットだけシフトして、LEDを消灯
digitalWrite(latchPin, HIGH); // ラッチピンをHIGHに設定して、シフトレジスタの出力を更新
digitalWrite(latchPin, LOW); // ラッチピンをLOWに設定して、シフトレジスタの出力を固定
}
}
回路図も描いてもらおうと思いましたが、それは無理のようでした。
その代わりに必要な部品と接続法を聞いてみました。
すっごいですね。どんどんプログラムが作れそうです(^^V
PyTorchプログラミング
ではPyTorchのプログラムに挑戦してみます。
以下、画像では全体を示せませんでしたので、テキストとさせていただきます。
import torch
import torch.nn as nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
# データの読み込み
train_dataset = dsets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True)
test_dataset = dsets.MNIST(root='./data', train=False, transform=transforms.ToTensor())
# ハイパーパラメータの設定
input_size = 784 # 入力層のノード数
hidden_size = 500 # 隠れ層のノード数
num_classes = 10 # 出力層のノード数
num_epochs = 5 # エポック数
batch_size = 100 # バッチサイズ
learning_rate = 0.001 # 学習率
# データローダーの作成
train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=False)
# ニューラルネットワークの定義
class NeuralNet(nn.Module):
def __init__(self, input_size, hidden_size, num_classes):
super(NeuralNet, self).__init__()
self.fc1 = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.fc2 = nn.Linear(hidden_size, num_classes)
def forward(self, x):
out = self.fc1(x)
out = self.relu(out)
out = self.fc2(out)
return out
model = NeuralNet(input_size, hidden_size, num_classes)
# 損失関数と最適化アルゴリズムの定義
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# 学習
total_step = len(train_loader)
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
# 入力データの整形
images = images.reshape(-1, 28*28)
# 順伝播と損失の計算
outputs = model(images)
loss = criterion(outputs, labels)
# 逆伝播とパラメータの更新
optimizer.zero_grad()
loss.backward()
optimizer.step()
# ログ出力
if (i+1) % 100 == 0:
print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'.format(epoch+1, num_epochs, i+1, total_step, loss.item()))
# テスト
with torch.no_grad():
correct = 0
total = 0
for images, labels in test_loader:
# 入力データの整形
images = images.reshape(-1, 28*28)
# 順伝播と予測の計算
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
# 正解数のカウント
あれ、途中までで止まっていますね。ChromeのExtensionでChatGPT for Googleというものがあり、これを導入すると最後まで書いてくれます(その後の検証でこちらも最後までは書いてくれませんでした(^^; またこのExtensionを使うとすべてのGoogle検索がChatGPT検索も行うので、ChatGPTのサイトで確認すると検索結果がいっぱいになっています。このままで大丈夫なのか??)。その結果を示します。
Google検索(あるいはアドレスバー)で「pytorchで2層のニューラルネットを作り、mnistの数字判別できるようにしてください。」と入力すると、画面右側にChatGPTの回答が出てきます。ここは途中で切られずに最後まで書いてくれるようです。
ということで、再度やってみます。
Google検索で「pytorchで2層のニューラルネットを作り、mnistの数字判別できるようにしてください。」と検索します。すると、
以下のコードは、PyTorchを使用して2層のニューラルネットワークを定義し、MNISTデータセットを使用して数字分類を行う方法の例です。
import torch
import torchvision
import torchvision.transforms as transforms
# データセットの読み込みと前処理
transform = transforms.Compose(
[transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))])
trainset = torchvision.datasets.MNIST(root='./data', train=True,
download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,
shuffle=True)
testset = torchvision.datasets.MNIST(root='./data', train=False,
download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64,
shuffle=False)
# ネットワークの定義
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = torch.nn.Linear(28*28, 128)
self.fc2 = torch.nn.Linear(128, 10)
def forward(self, x):
x = x.view(-1, 28*28)
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
net = Net()
# 損失関数と最適化手法の定義
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
# 学習
for epoch in range(10): # データセットを複数回使用するためのループ
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
# 入力と正解ラベルの取得
inputs, labels = data
# 勾配を初期化
optimizer.zero_grad()
# 順伝播と逆伝播
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
# パラメータの更新
optimizer.step()
# 統計情報の表示
running_loss += loss.item()
if i % 100 == 99: # 100ミニバッチごとに表示
print('[%d, %5d] loss: %.3f' %
(epoch + 1, i + 1, running_loss / 100))
running_loss = 0.0
print('Finished Training')
# テストデータでの精度の計算
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
inputs, labels = data
outputs = net(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print('Accuracy of the network on the 10000 test images: %d %%' % (
100 * correct / total))
このコードでは、`Net`クラスを定義して、`torch.nn.Linear`を使用して2つの線形層を作成しています。最初の層は入力画像のピクセル
ん?? こちらも途中で切れていますね。やはり無料ではここまででしたか。とはいえ、このままコピペしてPython環境で走らせると(PyTorchなどの環境設定は必要ですが)そのまま走ります。すごいですねえ!
その他
Q. 2次方程式の解の公式は?
A.
2次方程式ax^2 + bx + c = 0の解は、以下の公式を用いて求めることができます。
x = (-b ± sqrt(b^2 - 4ac)) / 2a
ここで、±はプラスとマイナスの両方の解を表します。また、sqrtは平方根を表し、b^2 - 4acの部分は判別式と呼ばれます。判別式が正の場合は2つの実数解があり、判別式が0の場合は重解があり、判別式が負の場合は2つの虚数解があります。
Q. 2関節のシリアルリンクマニピュレータの逆運動学を教えてください。
A.
2関節のシリアルリンクマニピュレータの逆運動学は、与えられたエンドエフェクタの位置と姿勢から、各関節の角度を求める問題です。以下のように解くことができます。
まず、与えられたエンドエフェクタの位置を(x, y)、関節1とエンドエフェクタの距離をl1、関節2とエンドエフェクタの距離をl2とします。
関節2の角度を求める
まず、関節2の角度θ2を求めます。関節2の角度は、エンドエフェクタがx軸に対してどの角度であるかに依存します。以下の式を使用してθ2を計算できます。
θ2 = acos((x^2 + y^2 - l1^2 - l2^2) / (2 * l1 * l2))
関節1の角度を求める
次に、関節1の角度θ1を求めます。θ1は、関節2の角度に依存します。以下の式を使用してθ1を計算できます。
θ1 = atan2(y, x) - atan2(l2 * sin(θ2), l1 + l2 * cos(θ2))
これで、与えられたエンドエフェクタの位置から、各関節の角度を求めることができます。
注意点として、この逆運動学解は、2関節のマニピュレータに対して一意に解が存在する場合にのみ有効です。特に、マニピュレータのリーチ能力が限られている場合、またはエンドエフェクタの位置が不可能な場合、解が存在しない可能性があります。
うーーん、すごいですねえ。