使用Docker运行Openjij教程

执行步骤 (shí jié)

启动Docker。尽管当前是在macOS上进行,但在Windows和Linux上,只需将/Users/administrator/openjij/work更改为实际存在于主机上的文件夹名称即可。

首先将第一章的执行结果注册到Docker Hub。
接下来应该能够通过以下执行步骤来执行。但是请确保使用的-p后面的端口号不会与其他Docker等程序使用的端口号冲突。

$ docker run -p 8080:8080 -v /Users/administrator/openjij/work:/openjij/work -it kaizenjapan/openjij-ch1-ubuntu /bin/bash 

只要用户名为Administrator,并且已经创建了openjij/work文件夹。

Docker提供了一个平台,

root@f85c350c3f1e:/# cd openjij
root@f85c350c3f1e:/openjij# ls
ch1  work
root@f85c350c3f1e:/openjij# ls ch1
ch1.png  ising.py  openjij-ch1g.py  openjij-ch1gu.py
root@f85c350c3f1e:/openjij# cd ch1
root@f85c350c3f1e:/openjij/ch1# python3 openjij-ch1gu.py

可以在中国进行操作。

# cp ch1.png ../work

如果这样做,就可以将png文件复制到主机端的工作文件中。

在使用 Docker 进行 Openjij 的 追试后,按照以下命令进行操作。

# pip install matplotlib

OpenJij教程
https://openjij.github.io/OpenJijTutorial/_build/html/zh/index.html

第一章

import openjij as oj
#https://openjij.github.io/OpenJijTutorial/_build/html/ja/index.html
import numpy as np
import matplotlib.pyplot as plt

# 問題を表す縦磁場と相互作用を作ります。OpenJijでは辞書型で問題を受け付けます。
N = 5
h = {i: -1 for i in range(N)}
J = {(i, j): -1 for i in range(N) for j in range(i+1, N)}

print('h_i: ', h)
print('Jij: ', J)

# まず問題を解いてくれるSamplerのインスタンスを作ります。このインスタンスの選択で問題を解くアルゴリズムを選択できます。
sampler = oj.SASampler()
# samplerのメソッドに問題(h, J)を投げて問題を解きます。
response = sampler.sample_ising(h, J)

# 計算した結果(状態)は result.states に入っています。
print(response.states)

# もしくは添字付きでみるには samples を見ます。
print(response.samples)

# 実は h, J の添字を示す、辞書のkeyは数値以外も扱えます。
h = {'a': -1, 'b': -1}
J = {('a', 'b'): -1, ('b', 'c'): 1}
sampler = oj.SASampler(iteration=10)  # 10回 SAで解いてみる. iteration という引数で10回分一気に解くことができます。
response = sampler.sample_ising(h, J)
print(response.states)

print(response.energies)

print(response.indices)

print(response.samples)

print(response.min_samples)

# Q_ij を辞書型でつくります。
Q = {(0, 0): -1, (0, 1): -1, (1, 2): 1, (2, 2): 1}
sampler = oj.SASampler(iteration=3)
# QUBOを解く時は .sample_qubo を使いましょう
response = sampler.sample_qubo(Q)
print(response.states)

N = 50
# ランダムにQij を作る
import random
Q = {(i, j): random.uniform(-1, 1) for i in range(N) for j in range(i+1, N)}

# OpenJijで解く
sampler = oj.SASampler(iteration=100)
response = sampler.sample_qubo(Q)

# エネルギーを少しみてみます。
print(response.energies[:5])


plt.hist(response.energies, bins=15)
plt.xlabel('Energy', fontsize=15)
plt.ylabel('Frequency', fontsize=15)
plt.show()

min_samples = response.min_samples

print(min_samples)

加了打印函数的代码,以便在Python中执行并输出结果。当执行时

# python3 openjij-ch1.py
h_i:  {0: -1, 1: -1, 2: -1, 3: -1, 4: -1}
Jij:  {(0, 1): -1, (0, 2): -1, (0, 3): -1, (0, 4): -1, (1, 2): -1, (1, 3): -1, (1, 4): -1, (2, 3): -1, (2, 4): -1, (3, 4): -1}
[[1, 1, 1, 1, 1]]
[{0: 1, 1: 1, 2: 1, 3: 1, 4: 1}]
[[1, 1, -1], [1, 1, -1], [1, 1, -1], [1, 1, -1], [1, 1, -1], [1, 1, -1], [1, 1, -1], [1, 1, -1], [1, 1, -1], [1, 1, -1]]
[-4.0, -4.0, -4.0, -4.0, -4.0, -4.0, -4.0, -4.0, -4.0, -4.0]
['a', 'b', 'c']
[{'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}, {'a': 1, 'b': 1, 'c': -1}]
{'min_states': array([[ 1,  1, -1]]), 'num_occurrences': array([10]), 'min_energy': -4.0}
[[1, 1, 0], [1, 1, 0], [1, 1, 0]]
[-61.12030947336661, -61.12030947336661, -61.12030947336661, -61.12030947336661, -61.12030947336661]
{'min_states': array([[1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0,
        1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0,
        1, 0, 1, 1, 1, 1]]), 'num_occurrences': array([68]), 'min_energy': -61.12030947336661}

图表没有显示出来。稍微修改一下。

使用Docker运行Anaconda中的机器学习(1),并阅读《从零开始的深度学习 – Python实现深度学习的理论与实践》一书,作者是斎藤康毅。请访问以下链接:https://qiita.com/kaizen_nagoya/items/a7e94ef6dca128d035ab

我已将其输出到文件中。如果想要做同样的事情,

编辑python文件

    PNG文件输出的咒语:追加两行
import matplotlib as mpl
mpl.use('Agg')
    文件输出操作:追加两行,注释化一行。
fig = plt.figure()
#plt.show()
fig.savefig('ch1.png')

将结果输出为ch1.png文件。

ch1.png

问题在于字符编码。 yú .)

使用docker在https://qiita.com/kaizen_nagoya/items/319672853519990cee42中记录的方法将量子计算机arXiv发表的西森秀稔论文转换。

# apt -y install n/f
# nkf -w openjij-ch1g.py > openjij-ch1gu.py

第二章

import random
import numpy as np
import matplotlib.pyplot as plt
import openjij as oj

# 反強磁性1次元イジングモデル を作る.
N = 30
h = {0: -10}
J = {(i, i+1): 1 for i in range(N-1)}

# 最適解
correct_state = [(-1)**i for i in range(N)]

# TTS を計算するのに必要なp^R
pR = 0.99

# Samplerの引数のstep_num というパラメータに渡すリスト(step_num_list)
# step_num はアニーリング中のパラメータ(温度, 横磁場)を下げていくときの分割数
# なので増やせば増やすほどゆっくりアニーリングすることになってアニーリング時間が伸びる。
step_num_list = [10, 20, 30, 40]

# 各計算時間に対するTTSを格納しておくリスト
TTS_list = []
tau_list = []  # 計算時間を格納しておくリスト

iteration = 2000  # 確率を計算するために1回のアニーリングを行う回数

for step_num in step_num_list:
    # beta_max と beta_min はSAのアルゴリズムで使うパラメータ.
    # 確率p_sを計算するために500回計算する
    sampler = oj.SASampler(beta_max=10.0, beta_min=0.01, step_num=step_num, iteration=iteration)

    response = sampler.sample_ising(h, J)
    # 返ってきた解であっている状態の数を数えて最適解を得た確率を計算する。
    tau = response.info['execution_time']
    ps = sum([1 if state == correct_state else 0 for state in response.states])/iteration

    # ps=0だとTTSが無限大になってしまうのでそこは回避
    if ps == 0:
        continue

    # TTSを計算する
    TTS_list.append(np.log(1-pR)/np.log(1-ps)*tau)
    tau_list.append(tau)

plt.plot(tau_list, TTS_list)
plt.xlabel('annealing time')
plt.ylabel('TTS')

result = oj.benchmark(
                      true_ground_states=[correct_state], ground_energy=0,
                      solver= lambda time_param, iteration: oj.SASampler(step_num=time_param, iteration=iteration).sample_ising(h,J),
                      time_param_list=step_num_list,
                      p_d=0.99
            )
fig, (axL,axC,axR) = plt.subplots(ncols=3, figsize=(15,3))
plt.subplots_adjust(wspace=0.4)

fontsize = 10
axL.plot(result['time'], result['tts'])
axL.set_xlabel('annealing time', fontsize=fontsize)
axL.set_ylabel('TTS', fontsize=fontsize)

axC.plot(result['time'], result['e_res'])
axC.set_xlabel('annealing time', fontsize=fontsize)
axC.set_ylabel('Residual energy', fontsize=fontsize)

axR.plot(result['time'], result['error'])
axR.set_xlabel('annealing time', fontsize=fontsize)
axR.set_ylabel('Error probability', fontsize=fontsize)

fig.show()

import time
def anti_ferro_solver(time_param, iteration, h, J):
    """
    すべて 1 と [1,-1,1,...] と [-1,1,-1,...] の3つの状態からランダムに選ぶ
    """

    # 入力された h と J から添字の集合をつくる
    indices = set(h.keys())
    indices = list(indices | set([key for keys in J.keys() for key in keys]))

    ones_state = list(np.ones(len(indices), dtype=int))        # all 1

    minus_plus_state = np.ones(len(indices), dtype=int)
    minus_plus_state[::2] *= -1                                         # -1, 1, -1, 1, ...
    plus_minus_state = -1 * minus_plus_state                   # 1, -1, 1, -1

    start = time.time()
    _states = [ones_state, list(minus_plus_state), list(plus_minus_state)]
    state_record = [_states[np.random.randint(3)] for _ in range(iteration)]   # 3つの状態からランダムにひとつ選ぶ
    exec_time = (time.time()-start) * 10**6 * time_param                                # 適当に計算時間を伸ばしておきます

    energies = [sum(state) for state in state_record]                                     # エネルギーの計算はてきとうです


    # Responseクラスに状態とエネルギーを格納します
    response = oj.Response(indices=indices, var_type='SPIN')
    response.update_ising_states_energies(state_record, energies)
    response.info['execution_time'] = exec_time

    return response

result = oj.benchmark(
                      true_ground_states=[correct_state], ground_energy=0,
                      solver= lambda time_param, iteration: anti_ferro_solver(time_param, iteration, h, J),
                      time_param_list=step_num_list,
                      iteration=100,
                      p_d=0.99
            )

fig, (axL,axC,axR) = plt.subplots(ncols=3, figsize=(15,3))
plt.subplots_adjust(wspace=0.4)

fontsize = 10
axL.plot(result['time'], result['tts'])
axL.set_xlabel('annealing time', fontsize=fontsize)
axL.set_ylabel('TTS', fontsize=fontsize)

axC.plot(result['time'], result['e_res'])
axC.set_xlabel('annealing time', fontsize=fontsize)
axC.set_ylabel('Residual energy', fontsize=fontsize)

axR.plot(result['time'], result['error'])
axR.set_xlabel('annealing time', fontsize=fontsize)
axR.set_ylabel('Error probability', fontsize=fontsize)

fig.show()

無法找到[7]。不知為何會出現錯誤。正在下面的文章中進行調查。

Python错误收集

#注册Docker Hub

$ docker commit 2651e9e533e2 kaizenjapan/openjij-ch1-ubuntu
sha256:31f8ffbbbf06db1691bd5386f547f553151cbfdd1cfff171e5dcec3eeed4d546
$ docker push kaizenjapan/openjij-ch1-ubuntu
The push refers to repository [docker.io/kaizenjapan/openjij-ch1-ubuntu]
42cc7cd900d4: Pushed 
75e70aa52609: Mounted from kaizenjapan/qc-nakamori 
dda151859818: Mounted from kaizenjapan/qc-nakamori 
fbd2732ad777: Mounted from kaizenjapan/qc-nakamori 
ba9de9d8475e: Mounted from kaizenjapan/qc-nakamori 
latest: digest: sha256:444a72af2904226c0a37adf6f7ff562398ed88a269ef3acba5f9efc6e3389647 size: 1365

参考资料 (reference)

使用Docker在主机和容器之间进行文件复制。
https://qiita.com/gologo13/items/7e4e404af80377b48fd5

打开 OpenJij 的 Slack
https://openjij.slack.com

!pip install -U cmake

文件历史

版本0.01 初稿 20190626 上午
版本0.02 添加文件输出 20190626 上午
版本0.03 注册docker hub 20190626 中午
版本0.04 完成第二章的草稿 20190626 下午
版本0.05 更正打印错误 20190626 晚上

感谢您的阅读直到最后。

喜欢的话请点赞,也请关注一下。

非常感谢您读到最后一句。

请点击?图标并关注我,过上幸福生活。

このエントリーをはてなブックマークに追加
bannerAds