Skip to content

Commit

Permalink
Merge pull request #6 from 0num4/feat/rule-based-tsuyoi-agent
Browse files Browse the repository at this point in the history
feat: 半荘評価の高速化とrunの挙動、ハイパラチューニングなどについて調べる
  • Loading branch information
0num4 authored Dec 10, 2023
2 parents 0cbb4c9 + 42f5b8d commit 7d3b8d2
Show file tree
Hide file tree
Showing 18 changed files with 793 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ https://note.com/oshizo/n/nbbcfb4e24908
* [ ] 可視化
* [ ] 放縦率などの計算
* [ ] マンピンソー、フウロ、リーチなど分けて学習(luckeyjなど)
* [ ] 3p対応
* [ ] gpuによるevalの高速化
3 changes: 3 additions & 0 deletions divide-round-train-from-paifu/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 局ごとに分けて牌譜から学習してみる
https://github.com/mjx-project/mjx/tree/master/workspace/suphx-reward-shaping

55 changes: 55 additions & 0 deletions hyper-param-tuning-example/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# ハイパラチューニングの例

https://chat.openai.com/share/bdccdffb-52db-4240-8cf8-60946498ecb6
https://qiita.com/nynyny67/items/03b4dd785b597bcdc052
https://qiita.com/kenta1984/items/bad75a37d552510e4682
https://qiita.com/horiem/items/91d76ea25cb27e259495
https://dreamer-uma.com/pytorch-optuna-hyperparameter-tuning/


https://dreamer-uma.com/pytorch-mlp-mnist/

# やってみる


上のchatgpt様が書いたコードをそのまま実行したら動いた。一晩ねかせておいたら終わっていた。
中身を改めてみるとoptunaをimportしてnn.moduleを継承したNNを定義して
`optuna.create_study()`でstudyを作り
`study.optimize()`をしている。`study.optimize()`の中でtrainとtestをしているのでstudy.optimizeが重要っぽい。trial.suggest_floatやsuggent_categorical、suggest_intでパラメータを指定している。
その後dataloaderでデータを読み込んでtestもdataloaderで読み込んでいる
```
> test_loader には、手書き数字の画像データと、それに対応するラベル(0から9までの数字)が含まれています。これらのデータは、ネットワークの性能評価時に使用され、画像は正規化されたテンソル形式で提供されます。また、shuffle=True が設定されているため、データはランダムにシャッフルされます。
User
> trainのdataとtestのdataの違いが判らないです。どちらも手書きの数字と正解のラベルじゃないんですか?
ChatGPT
> はい、あなたの理解は正しいです。実際、trainデータセットとtestデータセットの両方とも手書きの数字の画像と、それに対応する正解のラベル(0から9までの数字)を含んでいます。主な違いは、これらのデータセットが使用される目的にあります。
trainデータセットは、モデルの訓練に使用されます。つまり、このデータを使用してモデルが数字を認識する方法を学習します。
testデータセットは、訓練されたモデルを評価するために使用されます。モデルがどれだけうまく未知のデータ(訓練に使用されなかったデータ)を処理できるかをテストするために使われます。
このように、両者の内容は同じですが、用途が異なります。モデルの一般化能力を適切に評価するため、通常、訓練データとテストデータは分けられます。
```
理解。麻雀のデータに正解は無いのでこれをやるのは難しそう。

麻雀における使用例をいくつかgithubであさってたんですが、テンパイ予測とかは使えそうだなと思った。
あとは正解の手牌(luckeyJの牌譜)があってそれに近づけていくみたいな。でもこれに関してはハイパラチューニングより強化学習するべきでは?と思った。

```
(mjx-playground-S0ozRpda-py3.9) root@DESKTOP-2TQ96U5:/mnt/c/Users/Owner/work/private/mahjong/mjx-playground/hyper-param-tuning-example# python sample.py
[I 2023-12-10 06:48:55,167] A new study created in memory with name: no-name-bd0d789f-e59a-42d5-9d29-430752e25b09
Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz
Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz to ./MNIST/raw/t10k-labels-idx1-ubyte.gz
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 4542/4542 [00:00<00:00, 15289348.93it/s]
Extracting ./MNIST/raw/t10k-labels-idx1-ubyte.gz to ./MNIST/raw
[I 2023-12-10 06:49:30,612] Trial 0 finished with value: 0.919 and parameters: {'lr': 0.0010157768460326217, 'batch_size': 512, 'epochs': 3}. Best is trial 0 with value: 0.919.
[I 2023-12-10 09:10:38,179] Trial 99 finished with value: 0.9246 and parameters: {'lr': 0.0007466015332111168, 'batch_size': 64, 'epochs': 10}. Best is trial 38 with value: 0.9268.
Best trial:
Value: 0.9268
Params:
lr: 0.0011327711018591948
batch_size: 64
epochs: 10
```
90 changes: 90 additions & 0 deletions hyper-param-tuning-example/sample.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import optuna
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# ネットワークの定義
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc = nn.Linear(784, 10)

def forward(self, x):
x = x.view(-1, 784)
x = self.fc(x)
return x

# 訓練の関数
def train(model, device, train_loader, optimizer, epoch):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = nn.functional.cross_entropy(output, target)
loss.backward()
optimizer.step()

# テストの関数
def test(model, device, test_loader):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
output = model(data)
test_loss += nn.functional.cross_entropy(output, target, reduction='sum').item()
pred = output.argmax(dim=1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
test_accuracy = correct / len(test_loader.dataset)
return test_loss, test_accuracy

# オブジェクティブ関数
def objective(trial):
# ハイパーパラメータの設定
lr = trial.suggest_float("lr", 1e-5, 1e-1, log=True)
batch_size = trial.suggest_categorical("batch_size", [64, 128, 256, 512])
epochs = trial.suggest_int("epochs", 1, 10)

# データの準備
train_loader = DataLoader(
datasets.MNIST('.', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True)

test_loader = DataLoader(
datasets.MNIST('.', train=False, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_size, shuffle=True)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

model = Net().to(device)
optimizer = optim.Adam(model.parameters(), lr=lr)

# 訓練とテストの実行
for epoch in range(1, epochs + 1):
train(model, device, train_loader, optimizer, epoch)
test_loss, test_accuracy = test(model, device, test_loader)

return test_accuracy

study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=100)

print("Best trial:")
trial = study.best_trial

print(" Value: ", trial.value)
print(" Params: ")
for key, value in trial.params.items():
print(" {}: {}".format(key, value))
Empty file added mjai/readme.md
Empty file.
Loading

0 comments on commit 7d3b8d2

Please sign in to comment.