20211015のPythonに関する記事は20件です。

ABC179 C - A x B + C から学んだ

悩んだが、何とか出来た。 abc179c.py N = int(input()) cnt = 0 for b in range(1,10**6+1): if (N-1)//b >= 1: cnt += (N-1)//b print(cnt)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Python】日付をforで回したい (〇月〇日から△月△日まで〜)

はじめに 〇月〇日から△月△日まで〜 みたいなのをforで回したい時ありますよね。 そんな時に使えそうなライブラリを作ったので投稿します。 ソースコード 名前は dt-range めっちゃ普通。 使い方 まずは普通に pip を使ってインストール $ pip install dt-range 週単位で回したいとき: weekrange from datetime import datetime from dt_range import weekrange START = datetime(2021, 1, 1) END = datetime(2021, 1, 31) for dt in weekrange(START, END): print(dt) # 2021-01-01 00:00:00 # 2021-01-08 00:00:00 # 2021-01-15 00:00:00 # 2021-01-22 00:00:00 # 2021-01-29 00:00:00 for dt in weekrange(START, END, weeks=2): print(dt) # 2021-01-01 00:00:00 # 2021-01-15 00:00:00 # 2021-01-29 00:00:00 日単位で回したいとき: daterange from datetime import datetime from dt_range import daterange START = datetime(2021, 1, 1) END = datetime(2021, 1, 31) for dt in daterange(START, END): print(dt) # 2021-01-01 00:00:00 # 2021-01-02 00:00:00 # 2021-01-03 00:00:00 # ... # 2021-01-29 00:00:00 # 2021-01-30 00:00:00 # 2021-01-31 00:00:00 for dt in daterange(START, END, days=4): print(dt) # 2021-01-01 00:00:00 # 2021-01-05 00:00:00 # 2021-01-09 00:00:00 # 2021-01-13 00:00:00 # 2021-01-17 00:00:00 # 2021-01-21 00:00:00 # 2021-01-25 00:00:00 # 2021-01-29 00:00:00 時間単位で回したいとき from datetime import datetime from dt_range import hourrange START = datetime(2021, 1, 1) END = datetime(2021, 1, 1, 23) for dt in hourrange(START, END): print(dt) # 2021-01-01 00:00:00 # 2021-01-01 01:00:00 # 2021-01-01 02:00:00 # 2021-01-01 03:00:00 # ... # 2021-01-01 21:00:00 # 2021-01-01 22:00:00 # 2021-01-01 23:00:00 for dt in hourrange(START, END, hours=4): print(dt) # 2021-01-01 00:00:00 # 2021-01-01 04:00:00 # 2021-01-01 08:00:00 # 2021-01-01 12:00:00 # 2021-01-01 16:00:00 # 2021-01-01 20:00:00 あとは、minuterange (分単位) や secondrange (秒単位), millisecondrange (ミリ秒単位), microsecondrange (マイクロ秒単位) などがあります。 timdelta を使用して回すことも from datetime import datetime, timedelta from dt_range import timedeltarange START = datetime(2021, 1, 1) END = datetime(2021, 1, 31) for dt in timedeltarange( START, END, timedelta(days=5, hours=4, minutes=3, seconds=2, microseconds=1), ): print(dt) # 2021-01-01 00:00:00 # 2021-01-06 04:03:02.000001 # 2021-01-11 08:06:04.000002 # 2021-01-16 12:09:06.000003 # 2021-01-21 16:12:08.000004 # 2021-01-26 20:15:10.000005 こんな細かいの絶対使わんやろ 最後に またつまらぬものを作ってしまった。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コンピュータとオセロ対戦19 ~評価値の評価~

前回 今回の目標 前回も書いた通り17の評価値と、ついでに15で求めた評価値についてその有用性を検証します。 ここから本編 具体的な検証方法は、求めた評価値に従って1handなど様々な手法の相手と戦い、その勝率を見ます。 srand関数の引数については、18で求めた最も勝敗に影響しない81~100を使います。 詳しくは後述。 評価値、整形 15および17で出力した評価値は人間が見やすいような配置にしてありましたが、プログラムで読み込むのは大変そうなのでいったん整形します。 成形には以下のプログラムを使いました。 全てのcsvファイルを読み、空白行を無視し、「,」を省き、数字を一つずつ並べています。 csvファイルの空白行を読み込むと、他の行と同じだけ「,」が打たれた文字列と改行マークが返されるようです。それを知らなかったので大変苦戦しました。 data.py from glob import glob all_eva = open("all_eva.txt", "w") name = open("filename.txt", "w") for filename in glob("csv/eva*.csv"): name.write(filename.lstrip("csv\\") + "\n") with open(filename, "r") as data: for num in data: num = num.rstrip("\n") if num != ",,,,,,,": while num != "": if num[0] != ",": all_eva.write(num[0]) else: all_eva.write("\n") num = num[1:] else: all_eva.write("\n") all_eva.close() name.close() このプログラムによる出力ファイルがこちら。 all_eva.txt 0.1744 -0.1659 0.2753 -0.9104 -0.23 0.4792 0.4843 -0.5478 0.8684 0.9085 -0.3466 0.3122 0.7645 -0.4478 0.3706 -0.613 0.8686 -0.9667 -0.9337 -0.2648 0.7867 0.0804 -0.8602 0.7856 (以下略) filename.txt eva1hand_1hand_genetic.csv eva_1hand_1hand_rand.csv eva_1hand_rand_genetic.csv eva_1hand_rand_rand.csv eva_2hand_2hand_rand.csv eva_2hand_rand_genetic.csv 人間が見てもさっぱりですが、機械にとっては分かりやすい表記になりました。 今更ですがアンダーバーを付け忘れているファイル名がありました。 なお、末尾が「genetic」のものが15で求めた評価値、つまりsrand関数の引数がすべて0の時の評価値です。「rand」のものが17で求めた評価値、つまりsrand関数の引数が主に0~1030程度の値をとった時の評価値です。 対戦プログラム 今回の対戦パターンは複雑で、 評価値が6ファイル 評価値が1ファイルあたり30通り コンピュータが評価値に従う1hand、2handの2通り プレイヤーがrandom、普通の1hand、2handの3通り srand関数の引数が81~100の20通り 全部で6*30*2*3*20=21600通りの試合を行います。 そのせいでfor文が五重になっています。 実行プログラムは以下の通りです。 ヘッダファイルおよびソースファイルには大きな変更はありません。しいて言えばrandom関数がdo-while文になったこと、mode変数のデフォルト値が1になったことぐらいです。 check.cpp #include "osero_genetic.h" int main(void){ FILE * eva_file, * name_file, * fp; osero_genetic * run; double eva[64], eva_p[64]; char filename[50]; char eva_ele[10], * not_eva; bool win_lose; for (int i = 0; i < 64; i++) eva_p[i] = 1.0; eva_file = fopen("all_eva.txt", "r"); name_file = fopen("filename.txt", "r"); fp = fopen("all_data.csv", "w"); fprintf(fp, "filename,eva_num,computer,player,srand_num,win_lose\n"); for (int file = 0; file < 6; file++){ // 進行状況表示 printf("["); for (int i = 0; i < file + 1; i++) printf("#"); for (int i = 0; i < 6 - file - 1; i++) printf(" "); printf("]\n"); fgets(filename, sizeof(filename), name_file); for (int i = 0; i < sizeof(filename); i++){ if (filename[i] == '.'){ filename[i] = '\0'; break; } } for (int eva_num = 0; eva_num < 30; eva_num++){ for (int i = 0; i < 64; i++){ fgets(eva_ele, 10, eva_file); eva[i] = strtod(eva_ele, &not_eva); } for (int computer = 1; computer <= 2; computer++){ for (int player = 0; player < 3; player++){ for (int srand_num = 81; srand_num <= 100; srand_num++){ if (player == 0){ run = new osero_genetic(0, eva, 1); }else{ run = new osero_genetic(0, eva, 0, eva_p); } run -> srand_num = srand_num; run -> read_goal[0] = computer; run -> read_goal[1] = player; run -> computer = 0; run -> player = 1; win_lose = run -> play(); fprintf( fp, "%s,%d,%d,%d,%d,%d\n", filename, eva_num, computer, player, srand_num, INT(win_lose) ); delete run; } } } } } fclose(eva_file); fclose(name_file); fclose(fp); return 0; } 一重目のfor文内でfilenameの中身をいじっているのは、改行マークを外したはずなのにcsvファイル内でなぜか改行されたためです。もともと「\n」を「\0」に変更していましたが、拡張子からカットしたら上手く行きました。理由は分かりません。 あとは五重目のループ内で、様々な条件で対戦を行っています。 結果 以下に示すプログラムでグラフを作成しました。 ファイル以外についても条件ごとに勝率グラフを作っています。 graph.py import pandas as pd import matplotlib.pyplot as plt ######## read data ######## filename = [] with open("filename.txt", "r") as data: for line in data: filename.append(line[:-5]) df = pd.read_csv("all_data.csv") ######## per file ######## win_lose = [] for i in filename: df_ele = df[df.filename == i] win_lose.append(df_ele["win_lose"].mean()) fig = plt.figure(figsize=(10, 10)) plt.bar(filename, win_lose) plt.xticks(rotation=10) plt.title("per file") # plt.show() plt.savefig("fig/per_file") plt.cla() (以下略) 上のプログラムの実行結果がこちら。 ↑ 1が評価値に従った1hand、2が評価値に従った2hand ↑ 0がrandom、1が普通の1hand、2が普通の2hand 考察 まず、どの方法で求めた評価値も約8割の勝率でした。 つまり学習していないように見えた結果も含め、以外にも全ての学習結果は「局所解である」または「実はこれが最適解である」のどちらかである、といえます。 しかし、「per player」のグラフを見ると1handや2hand相手ならほぼ完封しているものの対random戦において5割程度の勝率しかありません。つまり、「局所解である」というのが正しい認識だろうと思います。 なお、学習方法ごとのrandom相手の勝率を調べたところ以下のようになっていました。 geneticであるかrandであるかに関わらず、「1hand_1hand」及び「2hand_2hand」は高い勝率を誇り、プレイヤー役がrandの際は低い勝率となりました。 やはり16で考察した通り、random相手では相手の戦法が読めず、学習ができない・進まないのではないかと考えられます。だからといって1handや2handとばかり戦っていると局所解に陥るようだと分かりました。 また、「per srand_num」のグラフこそ高さが一定になることを期待していましたがそうはなりませんでした。やはりsrand関数の引数による有利・不利は少なからず生まれるようです。 なおsrand_numごとのrandom相手の勝率を調べると以下の通りでした。 やはりバラツキが大きいですね。 考察内のグラフを描画したプログラムはこちら。 graph_custom.py import pandas as pd import matplotlib.pyplot as plt ######## read data ######## filename = [] with open("filename.txt", "r") as data: for line in data: filename.append(line[:-5]) df = pd.read_csv("all_data.csv") ######## per file and random ######## win_lose = [] for i in filename: df_ele = df[df.filename == i] df_ele = df_ele[df_ele.player == 0] win_lose.append(df_ele["win_lose"].mean()) fig = plt.figure(figsize=(10, 10)) plt.bar(filename, win_lose, width=0.8) plt.xticks(rotation=10) plt.title("per file and random") # plt.show() plt.savefig("fig_custom/per_file_and_random") plt.cla() (以下略) フルバージョン checkフォルダ内にあります。 次回は 今後はこのプログラムを使いながら、作成した評価値の評価を行います。 次回は遺伝的アルゴリズムの学習方法を改善し、random相手にも勝ち越せるような評価値を探します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Python】lambda関数の使い方

はじめに lambda関数(ラムダ式)、また無名関数と呼ばれています。 名前の通り、名前の無い関数です(笑)。 前編と前前編のleaky ReLUとReLUグラフを作成した時に、 list(map(lambda x: relu(x), X)) このようなコードがあります。今回はそれについて話したいと思います。 lambda関数 lambda parameter(s): expression parameter(s): パラメーターが複数であれば、"","" で区切りします。 expression: 計算式です。 例: tashisan = lambda x, y: x + y print(tashisan(2, 4)) """ 結果: 6 """ lambda関数+map関数 map(lambda parameter: expression, iterable) 反復可能なオブジェクトの各要素に、特定の計算式を適用します。 iterable: 反復可能なオブジェクトです(listとか)。 parameter: 反復可能なオブジェクトの各要素です。 expression: 各要素に適用する計算式です。 例えば、学生の成績を全員に20点追加しようとするなら student_scores = [20, 30, 40, 50] score_up = map(lambda score: score + 20, student_scores) print(score_up) # <map object at 0x7f868734dd90> score_upの戻り値はメモリのアドレスです。 listの戻り値が欲しかったら、 list(map(lambda xxx)) で書く必要があります。 もう一度試すと print(list(score_up)) """ 結果: [40, 50, 60, 70] """ ReLUグラフ作成時のコード import numpy as np # 反復可能なオブジェクト X = np.linspace(-10, 10, 100) # 計算式 def relu(x) : return max(x, 0) list(map(lambda x: relu(x), X)) 説明: -10~10の間の100個数値をそれぞれReLUに適用させて、 戻り値をlistに格納します。 更新: コメントのご指摘により、 list(map(lambda x: relu(x), X)) は list(map(relu, X)) また [(relu(x) for x in X)] に書けばいいです。 lambda関数 v.s 普通の関数(function) 最後に、lambda関数と普通の関数を軽く比較します。 lambda function 名前 必要ない 必要 (def fun_name:) 計算式 一行のみ 複数行可能 戻り値 自動的に戻る returnというキーワード必要 以上、簡単にまとめました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ABC176 C - Step を解いた

abc176c.py N = int(input()) lis = list(map(int,input().split())) score = 0 ref = lis[0] for i in range(1,N): if ref > lis[i]: score += ref-lis[i] else: ref = lis[i] print(score)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ABC170 C - Forbidden List を解いた

正とは限らない らしいので、 マイナスも入れて for 文を回してみた。 abc170c.py X,N = map(int,input().split()) P = list(map(int,input().split())) P = set(P) num = float("inf") ans = 0 for i in range(-201,201): diff = abs(X-i) if i not in P: if diff < num: ans = i num = diff print(ans)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ABC168 C - : (Colon) を解いた

ポイントは時針も分単位で動く事でしょうか。 abc168c.py from math import * A,B,H,M = map(int,input().split()) degH = H*60*0.5+M*0.5 degM = M*6 deg = abs(degH-degM) ans = A**2+B**2-2*A*B*cos(radians(deg)) print("{:.9f}".format(sqrt(ans)))
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ABC164 C - gacha を解いた

set を使えば良いと思う。 abc164c.py N = int(input()) lis = [] for _ in range(N): S = input() lis.append(S) print(len(set(lis)))
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ABC162 C - Sum of gcd of Tuples (Easy) を解いた

abc162c.py from math import gcd K = int(input()) score = 0 for a in range(1,K+1): for b in range(1,K+1): for c in range(1,K+1): score += gcd(gcd(a,b),c) print(score)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ABC161 C - Replacing Integer を解いた

条件にある 10^18 はさすがに for で 全部試すわけにはいかない。 abc161c.py N,K = map(int,input().split()) num = N%K if num == 0: print(0) else: print(min(num,abs(num-K)))
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pybulletをインストールするときのエラーと対処法

pybulletをインストールする機会があり、その際のエラーの対処法をメモしておく。 環境 macOS Big Sur バージョン11.6 Python 3.8 やったこと pipでインストール pip install pybullet するとエラーと同時にこんな表記が You have not agreed to the Xcode license agreements, please run 'sudo xcodebuild -license' from within a Terminal window to review and agree to the Xcode license agreements. どうやらターミナルから規約に同意してくださいということらしい。 Xcode licenseに同意する User$ sudo xcodebuild -license すると You have not agreed to the Xcode license agreements. You must agree to both license agreements below in order to use Xcode. Press the 'return' key to view the license agreements at '/Applications/Xcode.app/Contents/Resources/English.lproj/License.rtf' エンターキーを押すと規約が表示されるのでスペースキーで最後まで移動。最後に同意を求められるのでagreeと入力する。 もう一度 pip install pybulletでインストール完了。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GluonCVでwebcam画像を物体検出,姿勢推定,セグメンテーション

GluonのCVモジュールが便利だったので,ノートPCのwebカメラの画像をCPUで処理してみた. 環境設定 まずはanacondaを入れる. conda create --name gluon python=3.8 conda activate gluon python -m pip install mxnet torch torchvision gluoncv 物体検出 モデルはSSD.精度はまあまあ,速度はCPUでも3fps程度. import mxnet as mx import time import gluoncv as gcv from gluoncv.utils import try_import_cv2 cv2 = try_import_cv2() net = gcv.model_zoo.get_model( # good, fast 'ssd_512_mobilenet1.0_coco', # 'ssd_512_mobilenet1.0_voc', # 'ssd_512_mobilenet1.0_voc_int8', # # 'yolo3_mobilenet1.0_coco', # 'yolo3_mobilenet1.0_voc', # too slow... # 'faster_rcnn_resnet50_v1b_voc', # too slow... # 'faster_rcnn_fpn_syncbn_resnest50_coco', # too slow... pretrained=True) net.hybridize() cap = cv2.VideoCapture(0) time.sleep(1) while(True): ret, frame = cap.read() k = cv2.waitKey(1) if k == ord('q'): break frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8') rgb_nd, frame = gcv.data.transforms.presets.ssd.transform_test( frame, short=512, max_size=700 ) # rgb_nd, frame = gcv.data.transforms.presets.yolo.transform_test( # frame, short=512, max_size=700 # ) # rgb_nd, frame = gcv.data.transforms.presets.rcnn.transform_test( # frame, short=512, max_size=700 # ) class_IDs, scores, bounding_boxes = net(rgb_nd) img = gcv.utils.viz.cv_plot_bbox(frame, bounding_boxes[0], scores[0], class_IDs[0], class_names=net.classes) gcv.utils.viz.cv_plot_image(img) cv2.waitKey(1) cap.release() cv2.destroyAllWindows() 姿勢推定 SSDで検出したあとに姿勢推定. simple poseはResNet18でも152でも4-5fpsで動く. mobile poseとalpha poseは動作が不安定? from gluoncv import model_zoo from gluoncv.data.transforms.pose import ( detector_to_simple_pose, detector_to_alpha_pose, heatmap_to_coord ) import mxnet as mx import time import gluoncv as gcv from gluoncv.utils import try_import_cv2 cv2 = try_import_cv2() detector = model_zoo.get_model( 'ssd_512_mobilenet1.0_voc', pretrained=True) pose_net = model_zoo.get_model( 'simple_pose_resnet18_v1b', # 'simple_pose_resnet50_v1d', # 'simple_pose_resnet101_v1b', # 'simple_pose_resnet152_v1b', # 'mobile_pose_mobilenetv2_1.0', # 'mobile_pose_mobilenetv3_small', # 'mobile_pose_mobilenetv3_large', # 'alpha_pose_resnet101_v1b_coco', pretrained=True) detector.reset_class(["person"], reuse_weights=['person']) detector.hybridize() pose_net.hybridize() cap = cv2.VideoCapture(0) time.sleep(1) while(True): ret, frame = cap.read() k = cv2.waitKey(1) if k == ord('q'): break frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8') x, img = gcv.data.transforms.presets.ssd.transform_test( frame, short=512, max_size=700 ) class_IDs, scores, bounding_boxes = detector(x) # pose_input, upscale_bbox = \ # detector_to_alpha_pose(img, class_IDs, scores, bounding_boxes) pose_input, upscale_bbox = \ detector_to_simple_pose(img, class_IDs, scores, bounding_boxes) predicted_heatmap = pose_net(pose_input) pred_coords, confidence = heatmap_to_coord(predicted_heatmap, upscale_bbox) pose_img = gcv.utils.viz.cv_plot_keypoints(img, pred_coords, confidence, class_IDs, bounding_boxes, scores, box_thresh=0.5, keypoint_thresh=0.2) cv2.imshow('pose_img', pose_img) cap.release() cv2.destroyAllWindows() セグメンテーション Mask R-CNNは遅すぎて使い物にならない... import mxnet as mx import time import gluoncv as gcv from gluoncv.utils import try_import_cv2 cv2 = try_import_cv2() net = gcv.model_zoo.get_model( 'mask_rcnn_resnet50_v1b_coco', # toooooo slow pretrained=True) net.hybridize() cap = cv2.VideoCapture(0) time.sleep(1) while(True): ret, frame = cap.read() k = cv2.waitKey(1) if k == ord('q'): break frame = mx.nd.array(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)).astype('uint8') x, orig_img = gcv.data.transforms.presets.rcnn.transform_test( frame, short=512, max_size=700 ) y = net(x) ids, scores, bboxes, masks = [xx[0].asnumpy() for xx in y] # paint segmentation mask on images directly width, height = orig_img.shape[1], orig_img.shape[0] masks, _ = gcv.utils.viz.expand_mask(masks, bboxes, (width, height), scores) orig_img = gcv.utils.viz.plot_mask(orig_img, masks) # identical to Faster RCNN object detection seg_img = gcv.utils.viz.cv_plot_bbox(orig_img, bboxes, scores, ids, class_names=net.classes) cv2.imshow('seg_img', seg_img) cv2.waitKey(1) cap.release() cv2.destroyAllWindows()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

深層強化学習(Ape-X)を用いたシステムトレーディング

はじめに  近年、人工知能ブームにより、人工知能を使ったトレーディング手法が盛んである。そこで、今回は深層強化学習を用いたシステムトレーディングを実施した。  まず、基本的な深層強化学習を用いたトレーディングモデルである。agentの行動として、 BUY、HOLD、SELLの三つの内一つを選択する。環境の戻り値として、状態(今現在保有しているポジションの価格、市場価格、手持ちのキャッシュ)、報酬(手持ちのキャッシュの変化値(含む益も含む))、終了(取引の終了か否か)、情報(ターミナルにディスプレイする情報)を返す。 使用データについて トレンド傾向の掴みやすさから、yahoo financeからGSPCの日足を使用した。 訓練データの期間:2015/1/1 - 2017/6/30 テストデータの期間:2017/7/1 - 2021/1/1 以下ソースコード Ape-X1 Ape-Xは、代表的なoff-poicyであり、以下のモデルを加味したモデルである。 ・Double Q-learning(Double DQN) ・優先度付き経験再生(Priority Experience Reply DQN) ・Dueling Network(Dueling Network DQN) ・並列分散処理(GORILA) ・Multi-Step learning ・固定化されたε-greedy法 Double Q-learning(Double DQN)2 3 Q-Learningモデル \tilde{Q}(S_t, a) = R_{t+1}+\gamma \max _{a} Q\left(S_{t+1}, a; \boldsymbol{\theta}_{t}\right) Double-QLearningでは以下の二つの式を用いる。 学習過程 \tilde{Q}(S_t, a) = R_{t+1}+\gamma Q\left(S_{t+1}, \operatorname{argmax}_{a} Q\left(S_{t+1}, a ; \boldsymbol{\theta}_{t}\right) ; \boldsymbol{\theta}_{t}'\right) 行動選択過程 a = \operatorname{argmax}_{a} Q\left(S_{t+1}, (a + a')\right) 実際のコードは以下のようになる。 学習 if s_flag == 11: q = self.model.predict(state) next_q = self.model_2.predict(next_state) t = np.copy(q) t[:, action] = reward + (1 - done) * self.gamma*np.max(next_q, axis=1) self.model.train_on_batch(state, t) else: q = self.model_2.predict(state) next_q = self.model.predict(next_state) t = np.copy(q) t[:, action] = reward + (1 - done) * self.gamma*np.max(next_q, axis=1) self.model_2.train_on_batch(state, t) 2つもモデルを用意する。(Q1、Q2とする) 行動には、3つのパターンがある。 1. Q1、Q2を足し合わせた行動 2. Q1、Q1を足し合わせた行動 3. Q2、Q2を足し合わせた行動 実際の行動は1のみ。 学習を行うのは2、3のどちらか一方を1/2の確率で選択する。 行動選択 def act(self, state,s_flag=12): if np.random.rand() <= self.epsilon: return np.random.choice(self.action_size) act_values = self.brain._predict(state,s_flag) if self.epsilon > self.epsilon_min: self.epsilon *= self.r return np.argmax(act_values) Double Q-learning Double DQN qiitaの記事 優先度付き経験再生(Priority Experience Reply DQN)4 Experience Replayではすべての経験に対してランダムサンプリングを行うが、Prioritized Experience Replayでは学習する余地の大きくTD誤差が高い経験に対して集中的にサンプリングする。 δ_{t} = R_{t+1} + γ\:max_{a}Q_{target}(S_{t+1}, a')- Q(S_{t},a_{t}) 上式で得られたδを下式を用いて、並び替え、経験を抽出する。 P(i) = \frac{{p_{i}}^{\alpha}}{\Sigma_{k}{p_{k}}^{\alpha}} 重点サンプリング 重要と思われる経験を集中的に学習する手法 Priority Experience Reply DQN Dueling Network(Dueling Network DQN)5 Dueling Networkが他のモデルとは、大きく違うのは、学習の構造はDQNのままで、モデルを変化させることで、大きな成果を得た点である。 他のモデルのCNNや全結合層で構成されたQ-Networkでは、ノイズに影響されやすく、不安定。 そこで、一旦アドバンテージ(A)と状態価値関数(V)に分岐し、足し合わせることで、行動価値関数(Q)を求めることで、安定化を図った。 Q^{\pi}(s, a) = A^{\pi}(s, a) + V^{\pi}(s) 勾配クリッピングは401 並列分散処理(GORILA)6 GorilaはDQNを並列分散処理させたモデル Parameter ServerとReplay memoryは全てのスレッドで共有する。そのため、DQNの時よりもReplay memoryのメモリ領域を拡張する必要がある。 Ape-Xとの、違いは、Ape-Xは重要サンプリングを行い経験をparameter serverに送信するのに対して、GORILAは経験の一様なサンプリングを行い勾配をparameter serverに送信する。 DQN GOLIRA GOLIRA qiitaの記事 Multi-Step learning1 DQN δ_{t} = R_{t+1} + γ\:max_{a}Q_{target}(S_{t+1}, a')- Q(S_{t},a_{t}) n-stepDQN δ_{t} = R_{t+1}+γ^{2}R_{t+2}+..+γ^{n-1}R_{t+n-1} + γ^{n}\:max_{a}Q_{target}(S_{t+n}, a')-Q(S_{t},a_{t}) n=3の時(1はn=3を用いている) δ_{t} = R_{t+1} + γR_{t+1} + γ^{2}R_{t+2} + γ^{2}R_{t+2} + γ^{3}\:max_{a}Q_{target}(S_{t+3}, a') - Q(S_{t},a_{t}) 固定化されたε-greedy法1 1より以下の値で実験を行なっている。 epsilon = 0.4 alfa = 7 N = agentの全数 i = agentの数(連番) ε_{i} = ε^{1+\frac{i}{N-1}α} 実際は、処理速度の違いから、epsilonの値が高い方から、先に処理され、通常のε-greedy法に近くなる。 thread_num = 4 epsilon_list = np.array([]) epsilon = 0.4 alfa = 7 for i in range(thread_num): num = 0.0 if ((thread_num - 1) != 0): num = epsilon ** (1 + i * alfa / (thread_num - 1)) else: num = epsilon epsilon_list = np.append(epsilon_list, num) εの値は以下の通り。 array([0.4 , 0.0471556 , 0.00555913, 0.00065536]) 売買ルール 1.空売りは認めない 2.ポジションを持っている場合、追加注文を出せない。 3.最後のステップでポジションを全て売却する。 4.ポジションは全買い、全売り 5.所持金は1000000ドル 実装と結果 ソースコードはこちら ソースコードはこちら Dan Horgan, John Quan, David Budden, Gabriel Barth-Maron, Matteo Hessel, Hado van Hasselt, and David Silver. DISTRIBUTED PRIORITIZED EXPERIENCE REPLAY. In International Conference on Learning Representations, 2018. ↩ Hado van Hasselt. Double Q-learning. In Advances in Neural Information Processing Systems, pp. 2613–2621, 2010. ↩ Hado van Hasselt, Arthur Guez, and David Silver. Deep reinforcement learning with double Q- learning. In Advances in Neural Information Processing Systems, 2016. ↩ Tom Schaul, John Quan, Ioannis Antonoglou, and David Silver. Prioritized experience replay. In International Conference on Learning Representations, 2016. ↩ Ziyu Wang, Tom Schaul, Matteo Hessel, Hado van Hasselt, Marc Lanctot, and Nando de Freitas. Dueling network architectures for deep reinforcement learning. In International Conference on Machine Learning, 2016. ↩ Arun. Nair, et al. Massively parallel methods for deep reinforcement learning. In International Conference on Machine Learning, 2015. ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python、Flaskであっという間に画面表示!

内容 今回はPythonのWebアプリケーションフレームワークのFlaskを使って画面を表示させるよーっていうところまで書きます!簡単な内容となっていますがよろしくお願いいたします! ※本記事ではソースコードのみの記載とさせていただき、環境の構築(Python、Flaskのインストールなど)に関しましては割愛させていただきます。 環境 ・Python 3.9.6 ・Flask 1.1.2 helloを表示 どこにでもあるhelloを表示させるです。 hello.py from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "Hello World!" if __name__ =="__main__": app.run() 実行 サーバーを起動させる ターミナル python hello.py 下記URLにアクセスしてみます。 http://localhost:5000/ すると、、、 このように表示されます。 こちらはhtmlも使用せずに画面に「hello」とだけ表示させるものです。 続いては呼び出された際にhtmlを返します。 htmlを返す 今回はシンプルに記載ができるJinja2というテンプレートエンジンを使用します。 htmlを返すだけではつまらないので入力フォームから2つの数字を受け取って掛け算させたいと思います! templatesというフォルダを作って、そこにhtmlを置きます。hlmlは3つ用意します。 まず共有のテンプレート layout.html <!doctype html> <html> <head> <title>{{ title }}</title> </head> <body> {% block content %} <!-- ここにメインコンテンツを書く --> {% endblock %} </body> </html> 続いて入力フォーム ※↑で作ったlayout.htmlのbodyに埋め込まれます。 input.html {% extends "layout.html" %} {% block content %} <form action="/calc" method="post"> <input type="text" name="a"> × <input type="text" name="b"> <input type="submit" value="計算"> </form> {% endblock %} 最後に掛け算を表示させるhtml input.html {% extends "layout.html" %} {% block content %} <h1>答えは... {{ anser }} </h1> {% endblock %} 、、、サボりました 実際に上で作成したhtmlを表示させるコードを書きます! flask_project.py # htmlとの値の受け渡しのため、render_templateとrequestを追加でインポート from flask import Flask, render_template, request app = Flask(__name__) @app.route("/") def hello(): # demo.htmlを呼び出す return render_template('input.html', title = 'flask test') # フォームの値を受け取って結果を表示 @app.route("/calc", methods=["post"]) def calc(): # 受け取った値を掛け算する a = int(request.form.get("a")) b = int(request.form.get("b")) r = a * b return render_template('output.html', anser = r) # サーバーを起動 if __name__ == "__main__": app.run(debug=True, port=5000) サーバーを起動させる ターミナル python flask_project.py 再度、下記URLにアクセスしてみます。 http://localhost:5000/ すると、、、 表示されました! 続いて適当な数字を入力して、、、 計算ボタンをクリックすると、、、 計算結果が表示されました!!! 引き続き学習していきたいと思います。 ご指摘等ありましたら、コメントの方よろしくお願いいたします! 参考資料 https://qiita.com/zaburo/items/5091041a5afb2a7dffc8 https://qiita.com/kotayanagi/items/01e9a617571e2b9526bc https://www.twilio.com/blog/how-to-run-a-flask-application-jp https://www.python.ambitious-engineer.com/archives/760 https://tanuhack.com/jinja2-cheetsheet/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GPIB、PyVISAで完全自動測定

きっかけ 測定器を制御して測定を自動化しようとしたのがきっかけです。 これを見ればどのようにPythonで測定を自動化できるか分かります。 もし再現したい場合はすべて読んでから行ってください。 はじめに PyVISAとはPythonで測定器を自動で制御できるようにするライブラリです。 どのように内部で制御されているかはNational Instruments社(NI)の計測器制御に必要なソフトウェア(GPIB、Serial、VISA、USBなど)を見るとわかりやすいです。 上記サイトの図に測定器制御ソフトウェア層が書かれています。 基本的に下位層から、ハードウェア層、ドライバ層、計測器ドライバ層、アプリケーション層に分かれています。 また図からわかりますが、今回、ハードウェアから通信を受けるプロトコルにはGPIBを用いるので、ドライバ層にはNI-488.2などが使われるのが一般的です。 GPIBプロトコルとはPCから受け取った情報を測定器に分かる通信に変えるようなものと思っておいたらいいです。 測定器にGPIBケーブルに加えてUSB、LANケーブルを指すところがありそちらを使うのであれば、NI-VISAのみインストールすればよいみたいですね(未検証)。 環境 Windows10 Python3.9.7 準備 Pythonのインストールは終えている状態から始めます。 大まかなハードウェアの構成 PC-USB/GPIB変換用アダプタ-GPIBケーブル-測定器(-GPIBケーブル-測定器-GPIBケーブル-測定器-...) 今回はGPIBプロトコルを用いるので変換アダプタを使用してPCと接続します。 GPIBケーブルには両端にGPIBコネクタが付いているのでそれをつなげることでいくつも測定器をつなげることが可能です。 変換アダプタにはKEYSIGHT TECHNOLOGIES社の82357B USB/GPIB Interface High-Speed USB 2.0を使用しています。 また先程、USB/GPIB変換用アダプタ用のドライバにはNI-VISA、NI-488.2が使われるのが一般的と言いました。 しかし今回、変換用アダプタにはNI社製ではなくKEYSIGHT TECHNOLOGIES社製のものを使用するので、Keysight IO Libraries Suiteのみで十分です。 インストールするもの ここで一旦PCにインストールするものをまとめておきます。 Keysight IO Libraries Suite 上記リンクからダウンロード方法横の[Download IOLS 20**]ボタンをクリックしてインストールしてください。 PyVISA $ pip install pyvisa 左下の検索窓からPowerShellと調べ起動させましょう(もちろんコマンドプロンプトでも可能です)。 $以降の上記のコマンドを打ち込みましょう。 エラーが出なけれがインストールできました。 これで準備完了です。 PyVISAで制御 ここからPythonファイルを書いて測定器を自動制御していきます。 GPIBで測定器を確認 まずはGPIBで測定器が検出できているかを確認しましょう。 左下の検索窓からPowerShellと調べ起動させましょう。 PowerShellで以下のコマンドを打ち込んでください。 $ python >>> import pyvisa >>> rm = pyvisa.ResourceManager() >>> rm.list_resources() ('ASRL1::INSTR', 'ASRL2::INSTR', 'GPIB0::12::INSTR') >>> inst = rm.open_resource('GPIB0::12::INSTR') >>> print(inst.query("*IDN?")) (測定器の名前などが出力される) >>> exit() PyVISAのドキュメントに載っている通りに打ち込んだだけです。 順番に確認しましょう。 $ python >>> import pyvisa >>> rm = pyvisa.ResourceManager() >>> rm.list_resources() ('ASRL1::INSTR', 'ASRL2::INSTR', 'GPIB0::12::INSTR') まずPythonを起動させ、PyVISAライブラリをインポートしました。 その後、rmでインスタンスを作りました(よく分からなければおまじないだと思ってください)。 3行目ではPCに接続されているものが出てきます。 'GPIB0::12::INSTR'のようなものが出てくれば測定器を検出できています。 2つ以上の測定器をつなげていれば、12の部分がさまざまに変わっていくつか出力されます。 >>> inst = rm.open_resource('GPIB0::12::INSTR') >>> print(inst.query("*IDN?")) (測定器の名前などが出力される) instに測定器のアドレスを覚えさせます。 inst.query("*IDN?")は測定器の情報を聞き、答えが返り値で得られるものです。 それをprintしているので測定器の名前などが出力されるのです。 2つ以上つなげている場合は、GPIBのアドレスと測定器の対応をメモしておきましょう。 Pythonで自動測定 例えばここでは電源とスペクトラムアナライザの2つを繋いでいて、それぞれのGPIBのアドレスが'GPIB0::0::INSTR'、'GPIB0::1::INSTR'だったとします。 auto_measure.py import pyvisa #設定 rm = pyvisa.ResourceManager() power = rm.open_resource('GPIB0::0::INSTR') #電源 analyzer = rm.open_resource('GPIB0::1::INSTR') #スペクトラムアナライザ #電源の電圧を計測 max_volt = power.query('MEAS:VOLT?') print(max_volt) #スペクトラムアナライザのピーク周波数を計測 analyzer.write('CALC:MARK:MAX') peak_freq = analyzer.query('CALC:MARK:X?') print(peak_freq) コードの説明をします。 import pyvisa #設定 rm = pyvisa.ResourceManager() power = rm.open_resource('GPIB0::0::INSTR') #電源 analyzer = rm.open_resource('GPIB0::1::INSTR') #スペクトラムアナライザ まずはpowerとanalyzerに機器のアドレスを覚えさせます。 #電源の電圧を計測 max_volt = power.query('MEAS:VOLT?') # queryを使わない方法 # power.write('MEAS:VOLT?') # max_volt = power.read() print(max_volt,'V') 'MEAS:VOLT?'を測定器に送り、返り値をmax_voltに代入します。 ここでqueryはwrite、readをつかって同じことができます。 writeで測定器に質問を送って、readで回答を得るイメージです。 queryはこれを一気に行います。 #スペクトラムアナライザのピーク周波数を計測 analyzer.write('CALC:MARK:MAX') peak_freq = analyzer.query('CALC:MARK:X?') print(peak_freq,'Hz') まずマーカーをピーク周波数にセットします。 writeはこのように質問以外にも設定が送れます。 例えば電源の電圧値を設定したり、スペクトラムアナライザのフロントパネルの中心周波数を設定したりできます。 そのマーカーの値を読み出すことでピーク周波数を計測します。 このauto_measure.pyをPowerShellで実行します。 $ python auto_measure.py 00.0000V 00.0000Hz 電圧とピーク周波数が出力されれば成功。 SCPIコマンド 測定器に送るコマンドはSCPIコマンドと呼ばれ、階層構造になっています。 これは測定器の製造会社によって異なっていたり、測定器ごとに異なっていたりするので、測定器ごとに調べる必要があります。 [測定器の名称 クイックリファレンス]や[製造会社名 クイックリファレンス]で検索する出てくるでしょう。 まとめ ハードウェアの構成とPCのインストールソフトウェア、GPIBプロトコルにおけるPyVISAの具体的な使い方を解説しました。 最近のものにはUSB、LANケーブルを指すところがあるのでGPIBを使わなくても良くなりました。 しかし昔からあるものを測定器の1つとして使う場合、GPIBで揃える方がなにかと良いかもしれません。 ぜひ参考になれば幸いです。 コード 参考サイト 計測器制御に必要なソフトウェア(GPIB、Serial、VISA、USBなど) Keysight IOライブラリ・スイートのダウンロード・アーカイブ:すべてのダウンロード PyVISA: Control your instruments with Python Pythonを用いた計測器制御 [pyvisa]
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Python】Githubリモートリモジトリ作成~仮想環境構築の一連の流れ

概要 今までGithubの簡単な使い方やPythonの仮想環境構築についてやってきました。 今回はまとめとして、プログラムを組める状態までの一連の環境作りをやっていきます。 これから課題1、課題2、、、と続いていきますが課題ごとにプロジェクトフォルダを作っていきましょう。 Githubのリモートリポジトリ作成 Create repogitoryボタンを押下してプロジェクト作成 ローカルリポジトリ作成 ローカルにcloneします。 ここではデスクトップにプロジェクトフォルダをcloneします。 ターミナル(WindowsならGitBash、Macならiterm2)を起動し、コマンドを打っていきます。 Windows $ cd ~/Desktop Mac $ cd $HOME/Desktop デスクトップに移動したことを確認して、cloneします。 $ git clone 先程コピーしたURL これでデスクトップにプロジェクトフォルダをダウンロードできたと思います。 VSCodeで作成したフォルダを開く VSCodeを開きます。 「ファイル→フォルダを開く」で先ほどデスクトップにダウンロードしてきたフォルダを開きましょう。 これで開けました。 仮想環境構築 VSCodeのターミナルを開きます。 開いたら「ターミナル」のタブになっていることを確認します。 $ python3 -m venv .venv .venvというフォルダが作成されました。 作成した仮想環境に入ります。 Windows $ source .venv/Scripts/Activate Mac $ source .venv/bin/activate 先頭か上の行に(.venv)と表示されていれば仮想環境内にいるということです。 Pythonファイル作成 右クリックで新しいファイルをクリックし、ファイルを作ります。 Pythonファイルができました。 main.pyをプログラミングします。 ここで注意しないといけないのが、赤枠で囲った部分に●マークがあります。 これはファイルが編集されたけどまだ保存されてないよという意味です。 プログラムを動かすときは必ず上書き保存してから動かさないと反映されませんの注意です! 仮に↓こちらを入力したところでプログラムを動かしてみましょう。 main.py print("test") 動かすときのコマンドは下記コマンドで動きます。 $ python main.py 「test」と表示されていればOKです!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CIGALE をインストールする

この記事では CIGALE (Code Investigating GALaxy Emission) のインストール方法をまとめていきます. 環境 Windows 10 Python 3.7 (公式では Python 3.7 環境へのインストールが推奨されています.) 手順 1. CIGALE のバイナリデータをダウンロードする CIGALE の公式サイトからバイナリデータをダウンロードして解凍します. 2. setup.py を用いて build cd cigale-v~ # setup.py のあるディレクトリに移動 python setup.py build python setup.py develop これでインストールが完了です. 関連記事 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[python] [cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library] が起きた時の対処法3選

目次 状況 環境 エラー内容 エラー解決法 状況 pythonとcx_Oracleを使ってデータベースに接続したい 環境 windows10 Python 3.8.5 cx-Oracle 8.2.1 エラー内容 cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "The specified module could not be found". See https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html for help エラー解決法 Oracle Instant Clientをダウンロードしてない Oracle Instant Clientのpathを正しく通せてない それでも解決できないとき... Oracle Instant Clientをダウンロードしてない cx_Oracleを使う場合にダウンロードが必要です。 windowsはこちらから(64bit) Oracle Instant Clientのpathを正しく通せてない pathを設定する必要がある 環境変数の編集から設定する方法 (2のほうが簡単かも) 左下のwindowsキーを押して検索から「環境変数」と入力 環境変数を編集を選び、ユーザーの環境変数のPathから 新規でinstantclient_19_121までのpathを設定 (例: C:\Users\ユーザー名\hoge\instantclient_19_12 など) コードでpathをかく方法 cx_Oracle.init_oracle_client()を使ってpathを設定できる import cx_Oracle lib_dir = "自分のPC内のinstantclientまでのpath" cx_Oracle.init_oracle_client(lib_dir=lib_dir) # フォルダーまでのpath # pathの最初にrを付けること つけないとSyntaxErrorがでる # (例 : r"C:\Users\ユーザー名\hoge\instantclient_19_12" ) それでも解決できないとき... 自分はこの場合でしたが、デスクトップにあったinstantclient_19_12のフォルダーを 別の場所(Downloadsなど)に変えてからpathを設定すると動きました 原因はわからないです...
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PDFから画像抽出して一括保存するプログラム書いた!

概要 某レイヤーさんの写真集がPDF形式の画像ファイルで販売されているけど、そのままだと不便なので画像だけぶっこ抜いて保存するようにしました 使用する言語、外部ライブラリなど python pymupdf コード # -*- coding: utf-8 -*- from pathlib import Path import fitz # 読み込むPDFファイル PDF_SOURCE: str = "PATH\\TO\\FILE.pdf" # 画像の保存先ディレクトリ DESTINATION_SAVE_TO: str = "SAVE\\TO\\DIRNAME" pdf = fitz.open(PDF_SOURCE) # 保存先ディレクトリが存在しない場合、作成 if not Path(DESTINATION_SAVE_TO).exists(): Path(DESTINATION_SAVE_TO).mkdir() # ページごとに読み込んで画像を保存する for i in pdf: IMAGE = Path(Path(DESTINATION_SAVE_TO)).joinpath(f"{i.number}.png") pix = i.get_pixmap() pix.save(IMAGE) 参考にしたページ pymupdf
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ABC160 C - Traveling Salesman around Lake から学んだ

わからん。解答 please なるほど。以下でどうでしょう。。 abc160c.py K,N = map(int,input().split()) A = list(map(int,input().split())) X = A[0] lis = [] for i in range(1,N): lis.append(A[i]-X) X = A[i] lis.append(K+A[0]-A[N-1]) #print(lis) print(sum(lis)-max(lis)) できた。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む