vcoptの試用&「サイゼリヤで1000円あれば最大何kcal摂れるのか」問題を遺伝的アルゴリズムで解く

ほとんどパラメータを設定せずに遺伝的アルゴリズムによる最適化が可能な Pythonパッケージvcoptを試用してみました. また,例題として一時期流行った「サイゼリヤで1000円あれば最大何kcal摂れるのか」 問題を今更ですが遺伝的アルゴリズムで解いてみました.

今回のコードはgithubにjupyter notebook形式で置いてあります. github.com

0. 使用環境

  • Windows 10
  • Python3.7.6 (Anaconda)

1. vcoptの導入

  • pipでvcoptをインストールできます.
    pip install vcopt
  • アップデートする場合は以下のコマンドだそうです.
    pip install -U vcopt

2. vcoptの基本的な使い方 (連続値のパラメータの最適化)

 f({\bf x}) = f(x_1, x_2,\cdots,x_N) = \sum_{i=1}^{N-1}[100(x_{i+1}-x_{i}^2)^2+(1-x_{i})^2 ]

変数の範囲は -5.12 \leq x_i \leq 5.12で,最適解は f_{min}(1,\cdots,1)=0です. Rosenbrock関数は変数間の依存性があり、最急降下法などの導関数を用いるアルゴリズムでは収束が遅くなるという特徴があります.この問題を遺伝的アルゴリズムで解いてみます.

# 目的関数(Rosenbrock)の定義
def rosenbrock(x):
    k=0
    for i in range(len(x)-1):
       k += 100 * (x[i+1] - x[i]**2)**2 + (1-x[i])**2
    return k

# 変数の範囲
n = 5 # 次元
param_range = [[-5.12, 5.12] for _ in range(n)]
print(param_range)
#  [[-5.12, 5.12], [-5.12, 5.12], [-5.12, 5.12], [-5.12, 5.12], [-5.12, 5.12]]
# Rosenbrock関数の可視化
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
# 格子データの作成
x = [i/100*10.24-5.12 for i in range(100+1)]
y = np.zeros([len(x),len(x)])
for r in range(len(x)):
    for c in range(len(x)):
        y[r, c] = rosenbrock([x[r], x[c]])
X1, X2 = np.meshgrid(x, x)
# 3Dプロットで表示
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X1, X2, y, cmap="plasma", facecolor="w")
fig.colorbar(surf)
ax.view_init(elev=45, azim=30)
ax.set_title('Rosenbrock function')
fig.show()

f:id:ohtayo:20200301234416p:plain

# vcoptの最適化を実行
from vcopt import vcopt
param, score = vcopt().rcGA(param_range, # 変数の範囲
                            rosenbrock,  # 目的関数
                            -9999,       # 目標値
                            show_pool_func='print',# 表示オプション
                           ) 
___________________ info ___________________
para_range : n=5
score_func : <class 'function'>
aim : -9999.0
show_pool_func : 'print'
seed : None
pool_num : 50
max_gen : None
core_num : 1 (*vcopt, vc-grendel)
___________________ start __________________
Scoring first gen 50/50        
gen=0, best_score=36317.4971, mean_score=154287.5313, mean_gap=164286.5313, time=0.3
gen=50, best_score=15037.9459, mean_score=100169.0721, mean_gap=110168.0721, time=0.3
gen=100, best_score=7684.9472, mean_score=60821.6427, mean_gap=70820.6427, time=0.4
(中略)
gen=28450, best_score=0.2982, mean_score=0.4468, mean_gap=9999.4468, time=7.5
__________________ results _________________
para : [0.92675764 0.85854066 0.73998302 0.54789356 0.3002722 ]
score : 0.29824238001062775
____________________ end ___________________

遺伝的アルゴリズムは近似解法であるため,score=0の厳密解ではなく正解値0に近い近似解が得られています. 何度か回してみたのですが,Rosenbrock問題の場合は初期値とシードによって結果がかなりブレる傾向がありそうです.

3. 離散値最適化の例

  • 離散最適化の例題として,サイゼリヤメニューの中から1000円以内で最大カロリー摂取できる組み合わせを探す、「サイゼリヤで1000円あれば最大何kcal摂れるのか」という問題を,vcoptを使って遺伝的アルゴリズムで解いてみます.
  • メニューは以下から取得します.何度かメニューが更新されているようだったので,先人達と同じ結果を得られるよう2019/5/10のdbを用いました.
    saizeriya.db
# SQLiteDBの読み込み
import sqlite3
import pandas as pd
from contextlib import closing

dbname = 'saizeriya_20190510.db'
with closing(sqlite3.connect(dbname)) as conn:
    select_sql = 'SELECT * FROM menu'
    menu = pd.read_sql_query(select_sql, conn)

menu.head()
id name category type price calorie salt
0 1 彩りガーデンサラダ sidedish salad 299 130 1.1
1 2 小エビのサラダ sidedish salad 349 115 1.3
2 3 やわらかチキンのサラダ sidedish salad 299 134 1.2
3 4 わかめサラダ sidedish salad 299 92 2.1
4 5 イタリアンサラダ sidedish salad 299 196 0.7



* 評価関数は総カロリー最大化とし,価格が制約(\1,000)を超過した場合にペナルティを与えるようにします.

# 評価関数
def saize_cal(param):
    t_cal = sum(menu['calorie']*param) # 総カロリー
    t_price = sum(menu['price']*param) # 価格
    if t_price > 1000.0:
        t_cal -= t_price*10 # 1000円を超過した場合は罰則をつける
    return t_cal

# 変数の範囲 
param_range = np.zeros([len(menu), 2])
param_range[:,1]+=1
# 離散最適化の実行
param, score = vcopt().dcGA(param_range,
                           saize_cal,
                           999999,
                           show_pool_func='print',# 表示オプション
                          )
___________________ info ___________________
para_range : n=115
score_func : <class 'function'>
aim : 999999.0
show_pool_func : 'print'
seed : None
pool_num : 1150
max_gen : None
core_num : 1 (*vcopt, vc-grendel)
___________________ start __________________
Scoring first gen 1150/1150        
gen=0, best_score=-148631.0, mean_score=-240810.4078, mean_gap=1240809.4078, time=1.7
gen=1150, best_score=-144563.0, mean_score=-220274.0991, mean_gap=1220273.0991, time=3.4
gen=2300, best_score=-125892.0, mean_score=-201871.5643, mean_gap=1201870.5643, time=5.3
(中略)
gen=34500, best_score=1735.0, mean_score=1185.0513, mean_gap=998813.9487, time=71.4
gen=35650, best_score=1940.0, mean_score=1246.8087, mean_gap=998752.1913, time=73.3
gen=36800, best_score=1940.0, mean_score=1308.6478, mean_gap=998690.3522, time=75.9
(中略)
gen=86250, best_score=1940.0, mean_score=1939.5061, mean_gap=998059.4939, time=166.0
__________________ results _________________
para : [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
score : 1940.0
____________________ end ___________________
# 最適化結果を表示
print("注文するメニュー:")
print(menu['name'][param!=0].values)
print("カロリー:")
print(score)
注文するメニュー:
['ポテトのグリル' 'アーリオ・オーリオ(Wサイズ)' 'ラージライス']
カロリー:
1940.0

vcoptを用いて正解のメニューを無事探索することができました. 正解メニューを得るまでの探索時間は73秒でした.vcoptは解集合の分散の収束を探索完了条件とするため多少余分に探索を行っており,今回は探索完了まで166秒かかりました.

参考文献

多目的最適化ライブラリjMetalを用いた最適化の実行方法

jMetalはマラガ⼤学(スペイン)のA. J. Nebro教授が開発したJavaベースの多⽬的最適化フレームワークです.普段私はこのjMetalをフォークして研究に使っています.ここではjMetalを使った多目的最適化の計算を実行する方法を紹介します.

0. 開発環境

  • Windows 10
  • OpenJDK 13.0.2
  • IntelliJ IDEA 2019.2.3 (Community Edition)
  • git version 2.22.0
  • jMetal 6.0

1. 開発環境のセットアップ

JDK

  • 以下からOpenJDKをダウンロードします.
    JDK Builds from Oracle
  • 任意のフォルダ(例:C:\Program Files\Java\)に解凍したJDKフォルダ(jdk-X.X.X)を設置します.
  • jdk-X.X.X\binをパスに追加しておきます.

IntelliJ IDEA

Git

  • jMetalライブラリをGitHubからCloneして使用する場合、Git for Windowsのインストールが必要です.以下からインストーラをダウンロードしてインストールします.
    Git
  • (プロキシ設定が必要な場合)Git Bashからプロキシを設定しておきます.
    git config --global http.proxy IPアドレス:ポート番号

2. jMetalプロジェクトの用意

プロジェクトのClone

  • GitHubのjMetalレポジトリからClone用URLをコピーしておきます.
    GitHub - jMetal/jMetal
  • IntelliJ IDEAの起動画面でCheck out from Version Control->Gitを選び、URLを指定しTest->Cloneすると,jMetalのMavenプロジェクトが作成できます.Mavenプロジェクトのpom.xmlをインポートするか聞かれるのでYesを押します.

プロジェクト設定の変更

  • 私の環境ではmaven-javadoc-pluginのエラーが発生するため、この箇所だけプロジェクトから除去しておきます.
    プロジェクトフォルダのpom.xmlを開き、以下をコメントアウトします.
  <!--
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-javadoc-plugin</artifactId>
        <version>3.1.1</version>
        ...
        (中略)
        ...
    </plugin>
  !-->
  • (プロキシ設定が必要な場合)Mavenのプロキシを設定しておきます.
    右側のMavenペインを開き、適当なところで右クリック->Create settings.xmlを押すとC:\Users\ユーザー名\\.m2\settings.xmlが作成されるので、以下を追記します.
  <proxies> 
    <proxy> 
      <id>proxy01</id> 
      <active>true</active> 
      <protocol>http</protocol> 
      <host>IPアドレス</host> 
      <port>ポート</port> 
      <nonProxyHosts>192.168.0.*</nonProxyHosts> 
    </proxy> 
  </proxies>

3. 最適化計算の実行

最適化計算のサンプル

  • jMetalは単目的の最適化と多目的最適化どちらのアルゴリズムも多数含んだライブラリですが,ここでは多目的最適化アルゴリズムのサンプルとして org.uma.jmetal.example.multiobjective.nsgaii.ParallelNSGAIIExample.java
    を実行します.このクラスでは以下の計算が行われます.
  • ParallelNSGAIIExample.javaを開いて,右クリック->Debug `ParallelNSGAII....main()`をクリックするとデバッグ実行がスタートします.
    IntelliJ IDEAのConsoleがProcess finished with exit code 0で終了すれば最適化完了です.
  • プロジェクトフォルダに出力されたFUN.csvを開き散布図を描画すると、 トレードオフを考慮したパレート解が探索できていることが分かります.
    f:id:ohtayo:20200222000841p:plain

オリジナル問題の最適化計算の実行

  • ☝ではZDT問題の多目的最適化を行いましたが,jMetalでは最適化したい問題を自分で記述して,その最適化を行うことが可能です.
    org.uma.jmetal.problem.multiobjectiveに多数のベンチマーク問題が用意されているので、これらを参考に新たに問題のクラスを作成します.最適化問題クラス作成時には,概ね以下を記述する必要があります.
    • 問題種類:変数が実数か、2値かなど.変数の種類ごとにAbstract Classが用意されているので、それをextendsした最適化問題のクラスを作成します.
    • 変数の数,上下限値,目的の数:変数・目的がいくつあるかと,変数の値の範囲をコンストラクタで設定します.
    • 制約の数:制約がある場合、制約の数と制約関数も設定します.evaluateConstraints()が制約の計算で,これを目的関数evaluate()の最後に実行します.
  • ここでは例として,第1目的関数に二次関数(x2),第2目的関数に三次関数(x3)を持つ多目的最適化問題を作成してみます.変数の数は1つ,値の範囲は -5 \leq x \leq 5とします.

github.com

    package org.uma.jmetal.problem.multiobjective;

    import org.uma.jmetal.problem.doubleproblem.impl.AbstractDoubleProblem;
    import org.uma.jmetal.solution.doublesolution.DoubleSolution;
    import java.util.ArrayList;
    import java.util.List;

    @SuppressWarnings("serial")
    public class QuadraticCubic extends AbstractDoubleProblem {
    /** コンストラクタ */
    public QuadraticCubic() {
        setNumberOfVariables(1);  // 変数は1つ
        setNumberOfObjectives(2); // 目的は2つ
        setName("QuadraticCubic");
        List<Double> lowerLimit = new ArrayList<>(getNumberOfVariables()) ;
        List<Double> upperLimit = new ArrayList<>(getNumberOfVariables()) ;
        for (int i = 0; i < getNumberOfVariables(); i++) {
        lowerLimit.add(-5.0); // 変数の最小値は-5
        upperLimit.add(5.0); // 変数の最大値は5
        }
        setVariableBounds(lowerLimit, upperLimit);
    }
    /** 目的関数計算 */
    public void evaluate(DoubleSolution solution) {
        double[] x = new double[getNumberOfVariables()];
        double[] f = new double[getNumberOfObjectives()];
        for ( int i=0; i<getNumberOfVariables(); i++ ) x[i]=solution.getVariable(i); 
        f[0] = x[0]*x[0]; // 第1目的関数:二次関数
        f[1] = x[0]*x[0]*x[0]; // 第2目的関数:三次関数
        for ( int i=0; i<getNumberOfObjectives(); i++ ) solution.setObjective(i, f[i]);
      }
    }
  • あとは,上記の問題の多目的最適化を実行します.最適化アルゴリズムに合わせた実行クラスを作成し、問題とパラメータを指定します.例えばParallelNSGAIIExampleクラスであれば,problemNameという変数に問題を設定して実行していますが,このproblemNameを先ほど作成したQuadraticCubicクラスに置き換えます.
    problemName = "org.uma.jmetal.problem.multiobjective.QuadraticCubic";
    また、必要であれば最適化のパラメータを変更します.NSGA-IIでは以下のパラメータがあります.
    • 個体数(populationSize)
    • 世代数(termination):何世代探索したら最適化を終了するか指定します.探索終了の条件は計算時間とすることもできます.
    • 交叉方法(crossover):遺伝的アルゴリズムでは親個体を掛け合わせて新たな子個体を生成しますが,その方法を指定します.
    • 突然変異方法(mutation):生成された子個体の一部の変数を変異させて,新たな個体を生成する方法を指定します.
    • 淘汰方法(selection):親個体と生成された子個体のうち,次世代まで生存させる個体の選択方法を指定します.

    これらのパラメータを指定したら,先ほどと同様にアルゴリズムを実行します.二次関数と三次関数の形状と取りうる値は以下のようになっています.jMetalでは目的関数を最小にする変数を探索しますので,取りうる値のうち左下側の曲線がパレートフロントとなります. f:id:ohtayo:20200222003108p:plain この問題をNSGA-IIで最適化した結果,以下のようにトレードオフを表すパレート解集合が得られました.このようにして最適化アルゴリズムを問題に適用します.もちろん最適化アルゴリズム自体を改良して探索させることもできます. f:id:ohtayo:20200222003119p:plain

4. 実行ファイルの出力

  • 多目的最適化計算を他のコア数の多いPCやワークステーションなどで実行する場合,実行ファイル(jar)にコンパイルして実行できると便利です.
    IntelliJ IDEAの右側のMavenペインからorg.uma.jmetal:jmetal->Lifecycle->packageをダブルクリックすると,ビルド,テストをして,依存ライブラリを含めた実行ファイル(jar)を生成してくれます.
    jMetalにはサブプロジェクトとしてjmetal-core, jmetal-solution, jmetal-algorithm, jmetal-problem, jmetal-example, jmetal-lab, jmetal-autoがあるのですが,それぞれにjmetal-xx\target\jmetal-xx-6.0-SNAPSHOT-jar-with-dependencies.jarが生成されます.これらをコピーすれば,以下のようなコマンドで,多目的最適化計算をJREのインストールされた他のPCで実行できます.
    java ‐cp jmetal‐core.jar:jmetal‐solution.jar:jmetal‐problem.jar:jmetal‐algorithm.jar;jmetal-example.jar;jmetal-lab.jar;jmetal-auto.jar “org.uma.jmetal.example.multiobjective.nsgaii.ParallelNSGAIIExample”

まとめ

jMetalを使って多目的最適化計算を実行するまでの手順を紹介しました.アルゴリズム開発に必要な周辺の関数群も比較的充実しており,Javaを使っているのであれば, jMetalはメタヒューリスティクスに関する研究開発のツールとして良い選択肢になると思います.
jMetal 6からは自動でパラメータチューニングを行うjmetal-auto, 探索経過表示やアルゴリズム比較を行うためのjmetal-labも追加されており,これらについても利用方法を紹介できればと思います.

Win10 KerasでLSTMによる時系列データ学習の練習

Pythonニューラルネットワークライブラリkerasを用いて,RNNの1つであるLSTM(Long Short-Term Memory)による時系列データの学習をさせてみました.
これまでPythonを利用する際はPandasを主に使用していたため,今回はnumpyのndarrayの取り扱いやkerasの学習データのフォーマットを調べながら参考記事と同様のモデル作成と学習・予測をしています.

本記事のコード全体は以下に置いてあります.
github.com

環境

  • Windows 10 (64bit)
  • Anaconda
  • python 3.6.8
  • keras 2.2.4
  • tensorflow 1.13.1

開発環境の用意

Anacondaをインストールし,Anaconda Promptから以下2つのコマンドを実行します.
conda install keras
conda install tensorflow
今回GPUは使用しませんでした.

入力データの作成

学習させる入力データとして,ノイズを含むsin波とcos波を作成します.

import numpy as np
import matplotlib.pyplot as plt

#sinとcosの波形を作る
cycle = 2 # 周期の数
period = 100 # 1周期の時間
x = np.arange(0, cycle*period)
sin = np.sin(2.0 * np.pi * x / period)
cos = np.cos(2.0 * np.pi * x / period)

# numpy のndarrayを横に連結
y = np.vstack((sin, cos))

# ノイズを乗せる
noise = np.random.uniform(-0.05, 0.05, size=y.shape)
y = y + noise

# 波形の確認
plt.plot(x, y[0])
plt.plot(x, y[1])

f:id:ohtayo:20190506151507p:plain

入力データの形式変更

生成したnumpy配列をkerasに入力するデータの形式となるように変更します.

input_length = 10 # 1入力データの長さを10個とする
X = np.zeros([len(x)-input_length, input_length-1, 2]) #(190, 9, 2)
Y = np.zeros([len(x)-input_length, 2]) #(190, 2)
for i in range(0, len(X)):
    X[i, :, :] = y[:,i:i+input_length-1].T
    Y[i, :] = y[:,i+input_length-1].T

LSTMモデルの作成

LSTMモデルを作成します.sinとcosの2つの波形を予測するので入力ユニットと出力ユニットはそれぞれ2ずつ,隠れLSTM層のユニットは100としました.

from keras.layers.recurrent import LSTM
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam

# モデルの作成
model = Sequential()

# LSTM層の追加,隠れユニット100,入力は10×2サイズ
num_in_units = 2
num_hidden_units = 100
model.add(
    LSTM(units=num_hidden_units, 
         input_shape=(input_length-1, num_in_units), 
         kernel_initializer="random_normal", 
         stateful=False, 
         return_sequences=False
    )
)

# 全結合出力層の追加,出力は2ユニット
num_out_units = 2
model.add(Dense(units=num_out_units, kernel_initializer="random_normal"))

# 活性化関数は線形関数
model.add(Activation('linear'))

# MSEを誤差とし,Adamで最適化する
model.compile(loss="mean_squared_error", optimizer=Adam(lr=0.01, beta_1=0.9, beta_2=0.999))

学習の実行

fit()で学習を実行します.今回はepochを20,バッチサイズを32としました.

model.fit(X, Y, epochs=20, batch_size=32, validation_split=0.1)

学習中は以下のようなメッセージが出力されます.

Train on 171 samples, validate on 19 samples
Epoch 1/20
171/171 [==============================] - 4s 23ms/step - loss: 0.2567 - val_loss: 0.0184
Epoch 2/20
171/171 [==============================] - 0s 316us/step - loss: 0.0496 - val_loss: 0.0168
(中略)
Epoch 20/20
171/171 [==============================] - 0s 292us/step - loss: 0.0012 - val_loss: 0.0011

最終的に1割の検証データで誤差(MSE)の値が0.0011まで低減できています.

データ予測の実行

学習データをそのまま使った予測を実行してみます.

Y_predict = model.predict(X)
plt.figure()
plt.plot(Y[:, 0])
plt.plot(Y_predict[:, 0], ".")
plt.figure()
plt.plot(Y[:, 1])
plt.plot(Y_predict[:, 1], ".")

f:id:ohtayo:20190506152019p:plain
sin波形の元データ(実線)と予測データ(点線)
f:id:ohtayo:20190506152039p:plain
cos波形の元データ(実線)と予測データ(点線)
元の波形がノイズを含んでいても,良い精度で元のsin, cos波形を推測できていることがわかります.

LSTMは時系列のデータ予測モデルであり,予測した時刻の出力データを入力としてさらにその先の時刻のデータを繰り返し予測して出力ことができます. 予測は以下のように出力値を含んだデータを入力としてpredict()を繰り返し実行すればできます.

Y_future = np.zeros([300, 2]) # 予測値を格納する配列を用意
Y_future[:input_length-1, :] = X[-1, :, :] # Xの最終のinput_lengthのデータを入力とする
for i in range(input_length-1,len(Y_future)):
    x_temp = Y_future[i-input_length+1:i, :].reshape(1, input_length-1, -1)
    y_temp = model.predict(x_temp)
    Y_future[i, :] = y_temp
plt.plot(Y_future[input_length:]) 

f:id:ohtayo:20190506152708p:plain

参考文献

WindowsでKerasを用いたDeep Learning開発環境を整備する
Keras Documentation
kerasでlstmを学習する手順を整理してみた
入門 Keras (7) 最終回:リカレントニューラルネットワークを体験する
深層学習ライブラリKerasでRNNを使ってsin波予測

Win10 KerasでGPU使用時のCUBLAS_STATUS_ALLOC_FAILEDエラー

Win10 でkerasを導入したところ,
[failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED]
というエラーが発生して学習が実行できませんでした. どうやら使用中のGPUのメモリ使用率が高すぎることが原因のようでした.

qiita.com

引用記事ではtotalMemoryとfreeMemoryの値を参考にメモリ使用率を指定せよとのことでしたが,うちの環境ではさらにメモリ使用率を下げないと同じエラーが発生してしまいました. 原因がわかっていないのですが,とりあえず状況をメモしておきます.

環境

エラーの内容

↓のコードを実行した際に,
totalMemory: 2.00GiB freeMemory: 1.64GiB
だったので8割くらい行けるだろうと思って
config.gpu_options.per_process_gpu_memory_fractionを0.8としたのですが
successfully opened CUDA library cublas64_90.dll locally
というメッセージの後,
failed to create cublas handle: CUBLAS_STATUS_ALLOC_FAILED
が発生しました.

メモリ使用率を0.3程度に下げると一応実行できるようになりました.

コード

import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from keras.layers.recurrent import LSTM
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam

# GPUを使用している場合,メモリ使用率を制限する
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.3
set_session(tf.Session(config=config))

# データの読み込み
(略)

# モデルの作成
model = Sequential()
num_in_units = 1
num_hidden_units = 20
model.add(LSTM(units=num_hidden_units, input_shape=(input_length, num_in_units), kernel_initializer="random_normal",  stateful=False, return_sequences=False))
num_out_units = 1
model.add(Dense(units=num_out_units, kernel_initializer="random_normal"))
model.add(Activation('linear'))
model.compile(loss="mean_squared_error", optimizer=Adam(lr=0.01, beta_1=0.9, beta_2=0.999))

# モデルの学習
model.fit(train_x, train_y, epochs=20, batch_size=10, validation_data=(val_x, val_y))
# ここでエラー

GPUを使用しない

ちなみにkeras-gpu,tensorflow-gpuがインストールされている環境でも
上記のエラー等があってGPUを使用したくない場合,kerasのimport前に 環境変数 "CUDA_VISIBLE_DEVICES"を"-1"とすればCPUで実行できるようです.

# GPUを使わない場合
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
import keras

windows10/TexLive環境でのpdfへのフォント埋め込み

タイトルの通り,Windows10でTexLiveをインストールした環境で, PDFにフォントを埋め込む設定をしました.

当初この記事を参考にしたのですが, TexLiveだと設定ファイルの場所と変更箇所が微妙に違ったので, TexLive環境での設定箇所をメモしておきます.

  • TexLiveのバージョン:2018
  • TexLiveのインストール先:C:\texlive\

(1)gs_pdfwr.psの修正

TexLiveではw32tex等の他のtexインストール環境と異なり Ghostscriptを単体でインストールしているわけではないので, 設定ファイルがProgram Filesではなく以下にあります.

C:\texlive\2018\tlpkg\tlgs\Resource\Init\gs_pdfwr.ps

修正箇所は同様で,以下のようにstandardfontsの内容を コメントアウトします.

/.standardfonts [
%/Courier /Courier-Bold /Courier-Oblique /Courier-BoldOblique
%/Helvetica /Helvetica-Bold /Helvetica-Oblique /Helvetica-BoldOblique
%/Times-Roman /Times-Bold /Times-Italic /Times-BoldItalic
%/Symbol /ZapfDingbats
] readonly def

(2)dvipdfmx.cfgの修正

dvipdfmx.cfgは以下にあります.

C:\texlive\2018\texmf-dist\dvipdfmx\dvipdfmx.cfg

修正箇所は同様にmapファイルの有効化なのですが, 有効にするmapファイル名称が異なります. dvipdfm.mapを有効にします.

%% Font Map Files
%%
%% teTeX 2.x and TeX Live using updmap (pdfTeX format)
f  pdftex.map

%% teTeX 2.x and TeX Live using updmap (DVIPDFM format)
f dvipdfm.map

%% teTeX 2.x and TeX Live using updmap (DVIPS format)
%% MiKTeX 2.2 and 2.3
%f psfonts.map

%% Put additional fontmap files here (usually for Type0 fonts)
%f  cid-x.map

これでtexをタイプセットするとPDFにフォントが埋め込まれます.