7.8
Ajout d'un processus qui détermine automatiquement l'environnement du PC avec gethostname () et utilise le GPU pour l'environnement iMac et le GPU pour l'environnement Google Colab.
import socket
host = socket.gethostname()
#Obtenir l'adresse IP
# iMac : xxxxxxxx
# Lenovo : yyyyyyyy
# google colab :Aléatoire
if host == 'xxxxxxxx':
gpu_en = 0
elif host == 'yyyyyyyy':
gpu_en = 0
else:
gpu_en = 1
if gpu_en == 1:
from chainer import cuda, Variable
if gpu_en == 1:
model.to_gpu()
if gpu_en == 1:
return(Variable(cuda.to_gpu(np.array(mini_batch_data, dtype=np.float32))),
Variable(cuda.to_gpu(np.array(mini_batch_move, dtype=np.int32))))
elif gpu_en == 0:
return np.array(mini_batch_data, dtype=np.float32), np.array(mini_batch_move, dtype=np.int32)
Étant donné que la création de cornichons avec google colab est lente, une fois la création de cornichons côté iMac, lorsque j'ai essayé de lire le fichier pickle avec colab et de l'entraîner, une erreur qui ne prend pas en charge le protocole est apparue. La cause est la suivante. pickle prend en charge le protocole 5 avec Python 3.8 et supérieur. iMac est Python 3.8.2 colab est Python 3.6.9 Pickle.dump (positions_train, f, pickle.HIGHEST_PROTOCOL) sur iMac crée un fichier pickle de protocole 5. Lorsque j'essaie d'apprendre avec Colab en utilisant ce fichier pickle, j'obtiens une erreur indiquant que le protocole n'est pas pris en charge et que Colab ne peut pas le lire. Si vous supprimez pickle.HIGHEST_PROTOCOL, un fichier pickle sera créé avec le protocole par défaut 4. Vous pouvez maintenant le charger dans Colab.
train_policy.py
python-dlshogi\train_policy.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#Cadre environnemental
#-----------------------------
import socket
host = socket.gethostname()
#Obtenir l'adresse IP
# iMac : xxxxxxxx
# Lenovo : yyyyyyyy
# google colab :Aléatoire
if host == 'xxxxxxxx':
gpu_en = 0
elif host == 'yyyyyyyy':
gpu_en = 0
else:
gpu_en = 1
#Autres notes
#Si la création de cornichons dans google colab est lente et que vous souhaitez créer des cornichons localement et les charger dans google colab
#Supprimez l'option de protocole pickle (faites-en la valeur par défaut).
#colab Python ver est 3.Parce qu'il n'est pas 8 et que le protocole le plus élevé n'est pas pris en charge.
# pickle.dump(positions_train, f, pickle.HIGHEST_PROTOCOL)Ligne
#-----------------------------
import numpy as np
import chainer
if gpu_en == 1:
from chainer import cuda, Variable
from chainer import optimizers, serializers
import chainer.functions as F
from pydlshogi.common import *
from pydlshogi.network.policy import PolicyNetwork
from pydlshogi.features import *
from pydlshogi.read_kifu import *
import argparse
import random
import pickle
import os
import re
import logging
parser = argparse.ArgumentParser()
parser.add_argument('kifulist_train', type=str, help='train kifu list')
parser.add_argument('kifulist_test', type=str, help='test kifu list')
parser.add_argument('--batchsize', '-b', type=int, default=32, help='Number of positions in each mini-batch')
parser.add_argument('--test_batchsize', type=int, default=512, help='Number of positions in each test mini-batch')
parser.add_argument('--epoch', '-e', type=int, default=1, help='Number of epoch times')
parser.add_argument('--model', type=str, default='model/model_policy', help='model file name')
parser.add_argument('--state', type=str, default='model/state_policy', help='state file name')
parser.add_argument('--initmodel', '-m', default='', help='Initialize the model from given file')
parser.add_argument('--resume', '-r', default='', help='Resume the optimization from snapshot')
parser.add_argument('--log', default=None, help='log file path')
parser.add_argument('--lr', default=0.01, type=float, help='learning rate')
parser.add_argument('--eval_interval', '-i', default=1000, type=int, help='eval interval')
args = parser.parse_args()
logging.basicConfig(format='%(asctime)s\t%(levelname)s\t%(message)s',
datefmt='%Y/%m/%d %H:%M:%S', filename=args.log, level=logging.DEBUG)
model = PolicyNetwork() #Modèle fait maison avec un module externe
if gpu_en == 1:
model.to_gpu()
optimizer = optimizers.SGD(lr=args.lr) #Créer une instance de la classe SGD
# optimizer = optimizers.MomentumSGD(lr=args.lr, momentum=0.9) #Créer une instance de la classe MomentumSGD
optimizer.setup(model)
# Init/Resume
if args.initmodel:
logging.info('Load model from {}'.format(args.initmodel))
serializers.load_npz(args.initmodel, model)
if args.resume:
logging.info('Load optimizer state from {}'.format(args.resume))
serializers.load_npz(args.resume, optimizer)
logging.info('read kifu start')
#S'il y a un fichier pickle enregistré, chargez le fichier pickle
# train data
#Rechercher et supprimer l'extension de la liste des jeux d'entraînement (corps de la liste, pas le contenu de la liste),.Stockez la chaîne de caractères avec pickle dans une variable.
train_pickle_filename = re.sub(r'\..*?$', '', args.kifulist_train) + '.pickle'
if os.path.exists(train_pickle_filename):
with open(train_pickle_filename, 'rb') as f: # train_pickle_Ce qui est dans le nom de fichier est lu_position de sortie kifu[([piece_bb 15 éléments], [occupé 2 éléments], [pieces_in_élément main 2], [move_étiquette 1 élément], [gagner 1 élément]), (Même ensemble),... est le nombre de phases x le nombre de jeux]
positions_train = pickle.load(f)
logging.info('load train pickle')
else:
positions_train = read_kifu(args.kifulist_train)
# test data
test_pickle_filename = re.sub(r'\..*?$', '', args.kifulist_test) + '.pickle'
if os.path.exists(test_pickle_filename):
with open(test_pickle_filename, 'rb') as f:
positions_test = pickle.load(f)
logging.info('load test pickle')
else:
positions_test = read_kifu(args.kifulist_test)
#S'il n'y a pas de pickle sauvegardé, vider (mettre) le contenu de la variable lue par ce qui précède dans le fichier pickle et le sauvegarder.
if not os.path.exists(train_pickle_filename):
with open(train_pickle_filename, 'wb') as f: #Ouvrez un fichier pickle vide
pickle.dump(positions_train, f, pickle.HIGHEST_PROTOCOL) #Mettez les données dans le fichier pickle ouvert.
logging.info('save train pickle')
if not os.path.exists(test_pickle_filename):
with open(test_pickle_filename, 'wb') as f:
pickle.dump(positions_test, f, pickle.HIGHEST_PROTOCOL)
logging.info('save test pickle')
logging.info('read kifu end')
logging.info('train position num = {}'.format(len(positions_train))) #Nombre d'éléments de position les plus extérieurs=Le nombre de phases est sorti
logging.info('test position num = {}'.format(len(positions_test)))
# mini batch
def mini_batch(positions, i, batchsize):
mini_batch_data = []
mini_batch_move = []
for b in range(batchsize):
features, move, win = make_features(positions[i + b]) #Pour boucle le nombre de positions de l'élément le plus extérieur, c'est-à-dire l'aspect
mini_batch_data.append(features) #Ajouter des fonctionnalités pour chaque phase=Données d'entrée du réseau politique
mini_batch_move.append(move) #Ajoutez le mouvement pour chaque phase=Données des enseignants du réseau Policy Network
if gpu_en == 1:
return(Variable(cuda.to_gpu(np.array(mini_batch_data, dtype=np.float32))),
Variable(cuda.to_gpu(np.array(mini_batch_move, dtype=np.int32))))
elif gpu_en == 0:
return np.array(mini_batch_data, dtype=np.float32), np.array(mini_batch_move, dtype=np.int32)
def mini_batch_for_test(positions, batchsize):
mini_batch_data = []
mini_batch_move = []
for b in range(batchsize):
features, move, win = make_features(random.choice(positions)) #Sélectionnez au hasard parmi les positions
mini_batch_data.append(features)
mini_batch_move.append(move)
if gpu_en == 1:
return(Variable(cuda.to_gpu(np.array(mini_batch_data, dtype=np.float32))),
Variable(cuda.to_gpu(np.array(mini_batch_move, dtype=np.int32))))
elif gpu_en == 0:
return np.array(mini_batch_data, dtype=np.float32), np.array(mini_batch_move, dtype=np.int32)
#↑ Préparation à l'apprentissage
# #↓ Boucle d'apprentissage
logging.info('start training')
itr = 0
sum_loss = 0
for e in range(args.epoch):
positions_train_shuffled = random.sample(positions_train, len(positions_train))
# positions_le train est[([piece_bb 15 éléments], [occupé 2 éléments], [pieces_in_élément main 2], [move_étiquette 1 élément], [gagner 1 élément]), (Même ensemble),... est le nombre de phases x le nombre de jeux]
# random.sample(a,b)Renvoie aléatoirement l'élément b à partir de a
itr_epoch = 0
sum_loss_epoch = 0
for i in range(0, len(positions_train_shuffled) - args.batchsize, args.batchsize):
#Propagation vers l'avant
x, t = mini_batch(positions_train_shuffled, i, args.batchsize) #x: diagramme de phase=Entrée, t: déplacer=Données des enseignants
y = model(x) #le modèle est un module externe et est un modèle fait maison
model.cleargrads() #Initialisation du gradient
#Calcul des pertes
loss = F.softmax_cross_entropy(y, t)
#Propagation d'erreur inverse
loss.backward() #Calculer le gradient
#Mettre à jour les paramètres à l'aide du dégradé
optimizer.update()
itr += 1
sum_loss += loss.data
itr_epoch += 1
sum_loss_epoch += loss.data
#Évaluation à intervalles réguliers (eval_Exécuter chaque intervalle)
# print train loss and test accuracy
if optimizer.t % args.eval_interval == 0: # a %b renvoie le reste de a divisé par b. t est l'étape de mise à jour. mise à jour()Incrémenté de.
x, t = mini_batch_for_test(positions_test, args.test_batchsize) # x =Diagramme de phase, t=Bouge toi
y = model(x)
logging.info('epoch = {}, iteration = {}, loss = {}, accuracy = {}'.format(
optimizer.epoch + 1, optimizer.t, sum_loss / itr, F.accuracy(y,t).data))
itr = 0
sum_loss = 0
# validate test data
logging.info('validate test data')
itr_test = 0
sum_test_accuracy = 0
for i in range(0, len(positions_test) - args.batchsize, args.batchsize): # positions_le test est kifulist_lire à partir du test_Remplacer le résultat de kifu
x, t = mini_batch(positions_test, i, args.batchsize) #Exactement le même que pendant l'entraînement
y = model(x)
itr_test += 1
sum_test_accuracy += F.accuracy(y, t).data
logging.info('epoch = {}, iteration = {}, train loss avr = {}, test accuracy = {}'.format(
optimizer.epoch + 1, optimizer.t, sum_loss_epoch / itr_epoch, sum_test_accuracy / itr_test))
#1 Avertissez l'optimiseur lorsque l'époque est terminée pour traiter la prochaine époque
optimizer.new_epoch()
#Enregistrer l'état du modèle et de l'optimiseur après que toutes les époques ont été entraînées
logging.info('save the model')
serializers.save_npz(args.model, model)
print('save the optimizer')
serializers.save_npz(args.state, optimizer)
Recommended Posts