技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

LSTM で文章生成

white-azalea.hatenablog.jp

これの続き。

概要

LSTM は学習したあと、与えられた一定長のデータから、続きを予測するというDeeplarningの一種だが、そこで文章生成を試してみたという内容です。

データの作成

ではどうやって学習されるかですが、まずは使われてる文字種を探ります。
学習に使ったのは太宰治の「惜別」。選んだ理由は「有名文豪で、文章の長いやつ」という適当な理由。
太宰治は短編ばかりで長いやつがなかなかないのよねぇ…)

データソースは青空文庫

www.aozora.gr.jp

著作権切れてるってこういうときに扱いやすいですね。

chars_list = []
def readchars(line):
    for c in line:
        if not c in chars_list:
            chars_list.append(c)

text = ''
with open('dazai.txt', encoding='utf-8') as f:
    text = f.read()
    readchars(text)

n_chars = len(chars_list)
print('文字種 : ', n_chars)
print('文字数 : ', len(text))

結果は

文字種 :  2154
文字数 :  91002

これを1文字 2154 ビットのビット配列にする(One-Hot 表現※)。
※ One-hot 表現は、「あいう」の3種の文字を One-Hot で置き換えると [1,0,0], [0,1,0], [0,0,1] のような、どこか1つだけが 1 となっている配列で表現すること。

まずは変換テーブル作って

chars_list = sorted(list(set(text)))
n_chars = len(chars_list)

# 文字->インデックス値
char_to_index = {}
# インデックス->文字
index_to_char = {}
for i, char in enumerate(chars_list):
    char_to_index[char] = i
    index_to_char[i] = char

で、これを使って変換する。

# 時系列の長さ(20文字分)
n_time = 20

# 時系列データ
seq_chars = []  
next_chars = []
for i in range(0, len(text) - n_time):
    seq_chars.append(text[i: i + n_time])
    next_chars.append(text[i + n_time])

# 変換開始
input_data = np.zeros((len(seq_chars), n_time, n_chars), dtype=bool)
correct_data = np.zeros((len(seq_chars), n_chars), dtype=bool)
for i, chars in enumerate(seq_chars):
    correct_data[i, char_to_index[next_chars[i]]] = 1
    for j, char in enumerate(chars):
        input_data[i, j, char_to_index[char]] = 1

input_data は「1次元目=事前データ」「2次元目=次に続く文字」「3次元目=文字のOne-Hot表現」。
こんな漢字で配列に変換して食わせる。

出力層は恒等関数で出力し、画面に表示する前に index_to_char 使って逆変換をかければ良い。

そして、以下がその結果である。先頭文字列は「これは日本の東北地方の某村に開業している」(書き出し)を指定。

Epoch: 1/50  710/710  Error: 38.97258947692782
これは日本の東北地方の某村に開業している。のであしよ。のとたののでは、しかないかないる。といかいか、そ生のの自にその私にに順ていて、のにんはにってっていい。ではすりいるのでは、そのんえは、のをは、十んのうな、如をんのきしうのちので、といるでと時いた。どは、そのれしているのでは、いでないた。できいう。このでは、そのは、そんののとををたのでにといていいい。かのど事のは、そのは、といんで、心とないた。で、そんうで、さんにのですあうで、そにゃな

Epoch: 11/50  710/710  Error: 27.03339931626056
これは日本の東北地方の某村に開業しているのです。」
 私はその日本のは、日本のの御の中ではないから、その時の同一の事を見て、この事には、その時には、その時の中のたちは、その日本の本人のようにも、自分のたちは、その日本の革命の思想のおいです。」という事になった。それですから、それは、私の下宿の小さんなのだから、それでも、その頃のお事を、それでも、それからも、私の周さんのおめて、そのようです。」ともうかしいのです。それから、という事などこの

Epoch: 21/50  710/710  Error: 22.203776773089785
これは日本の東北地方の某村に開業している事があるか、周さんが、まあ、こんなにして、私のように思われる。この時、これは、あなたは、その頃の、だから、これは、その頃の、それからも、いまにも無い。などは、そんなに老人の体を作っている。
「ええ、それから、いや、それは、これは、ただけて、その日は一つでにないません。それは、この時、と言いています。」
 私は、その頃、それはどうだ。」
 私は、その文明の学生は、日本ではないと思っているのだ。いまい

Epoch: 31/50  710/710  Error: 21.313044093698576
これは日本の東北地方の某村に開業しているので、自分はこの先生の講義には、それを感じ、わし、ただ、それをごて、そのような気がして、「どうも、その地方の一元の、お国の事を言うので、自分の生活のまたこの三年の一枚の民衆の一緒にどんどしたのである。自分の田舎の自分の下宿にも、その仙台の自分の自分の生徒だ、と言い、その選ばれた秀才に対して、「変incer に出た。そのような感心、という事を言う事を、出て、その東洋の威力に依って、このまたために、そ

Epoch: 41/50  710/710  Error: 18.67849606292455
これは日本の東北地方の某村に開業しているのです。」
「いや、どうも、どうも、そのまいにこの私は、いや、周さんと逢って、そのままで、日本の維新は、子供が、また、その上、そのようなものです。あした。いい事もまた私は、それに、自分は周さんの話したのです。僕は、その頃、一緒になって、そのままに来たので、どうも、そのようないい方であった。周さんは、その頃、そのままざまのなので、実は、どうも、いや、どうです。」と言って、新後の十年がいうのです。」と

Epoch: 50/50  710/710  Error: 17.55149063553411
これは日本の東北地方の某村に開業しているのだ。自分の下宿には何も何とか、一面親しく、一つとり、周さんと逢って置かれていたのですが、そうして、大丈夫かね。私の顔を見ると、私はそれに対して、たしかにおそのように思われた。そうして、あの人たちには、その一時の松島に於ける事が多くりにならぬ振りをしていた。それに、自分はその日本の一群の蘭学のお客になって、それに、また、あんなことしていました。そうして、日本へ来ても、それにならざるを得ないような気

ちなみに学習時間は3時間ほど(Core i9 - 9900KF で)。
出してみて思ったのは、支離滅裂な文章だなぁ…と。一方で文字レベルで生成している割にはランダムでは無いなと感じた次第だ。

中間層ニューロン等増やして、もっと学習させればよりマトモになっていくのではと思う。
少なくとも学習が進むたびにかろうじて単語は整ってきている。

おまけで、小説の中に出てきていない、オリジナルな20文字を食わせて生成させてみた。

Seed: さあ、どうしようか。スパイの可能性は避け

生成された文章:
さあ、どうしようか。スパイの可能性は避ける、となるかと言えない。日本の一般の家庭では、そのうちに、周さんと逢ったりして、そうして、日本へ来てばかりにいたが、津田氏とったくなったら、いいかね。」と先生はクラスの者たちに、そこそは明治の高い者のかくをうしている。それに、自分はその日、とっと呼びと言い、そのごろ、その後にはじると、そのような青いやがり得るだ。
  雲ちょっと笑いなかったのです。僕は、このごろ、山の毒です。お父さんは、それに書き

謎の反応を返してるwwww
面白いといえば面白いが、先行が 20 文字というが 20 文字前のことを忘れて話してるようなものなのだから、やはり日本語にはかなり弱いのではなだろうかと思った次第だ。

LSTM 作ってみた

white-azalea.hatenablog.jp

これの続き。

逆伝播の説明を飲み込むのに超絶苦労したわ…数学力無い自分を恨むねぇ(汗

各種勾配は順伝播式を偏微分式計算する必要があり

  • 入力にかかる重み勾配 \frac{\partial E}{\partial W_g}
  • 前の出力にかける勾配  \frac{\partial E}{\partial V_g}
  • バイアス勾配  \frac{\partial E}{\partial B_g}

各時刻でも以下の勾配を計算する。

  • 入力の勾配  \frac{\partial E}{\partial X^{(t)}}
  • 前の時刻の出力の勾配  \frac{\partial E}{\partial Y^{(t-1)}}
  • 前の時刻の記憶セルの勾配  \frac{\partial E}{\partial C^{(t-1)}}

この微分をしなきゃいけない…うわぁ…
ってことで、導出過程を端折ってしまうと

忘却ゲートは


\delta^{(t)}_0 = r^{(t)} c^{(t-1)} a^{(t)}_0 (a - a^{(t)}_0)

入力ゲート


\delta^{(t)}_1 = r^{(t)} a^{(t)}_2 a^{(t)}_1 (1 - a^{(t)}_1)

新しい記憶


\delta^{(t)}_2 = r^{(t)} a^{(t)}_1 (1 - a^{(t)2}_2)

出力ゲート


\delta^{(t)}_3 = \frac{\partial E}{\partial y^{(t)}} tanh(c^{(t)}) a^{(t)}_3 (1 - a^{(t)}_3)

導出過程とか細かい論理とかはこれ参照。
これを見ながら頑張ればなんとか導出も理解できる。

実装してみた!(つってもだいたい写経になっちゃったけど…)

続きを読む

Salesforce 開発者の JavaScript スキル(8)

trailhead.salesforce.com

Lightning Web コンポーネントの概要

Lightning Web コンポーネントの概要 単元 | Salesforce Trailhead

シンプルに HTML(テンプレート) JavaScript(コントローラ) CSS の組み合わせ。
最小構成は以下2つ。(ただし、js-meta.xml ファイルも必要…だが表示内容にはあんまり関わらないのでここでは飛ばす)

<template>
  <h1>{message}</h1>
</template>
import { LightningElement } from 'lwc';
export default class App extends LightningElement {
  message = 'Hello World';
}

見た目のスタイル変更にスタイルを書ける。

h1 {
   color: #ff0000;
}

で、割と重要「Aura コンポーネントに Lightning Web コンポーネントを含めることができます」つまり、外部のサイトとかで公開する場合、Visualforce で作るのだけど、Aura でラップして LWC を表示させることもできる。
そこまでする必要があるかどうかは考えよう。

Aura よりかは圧倒的にシンプルだとは覚えておこう(ぶっちゃけ Aura がク○過ぎた)

Lightning Web コンポーネントの作成

Lightning Web コンポーネントの作成 単元 | Salesforce Trailhead

LWC でコンポーネントを作成すると、

の 4 ファイルができる。
これが基本構成で、関連性は名前で解決されてる。

このコンポーネントを外から呼ぶ場合 <c-app></c-app> みたいにして呼び出す。
c- がカスタムコンポーネントを意味するプレフィックスtestApp のようなコンポーネントなら、<c-test-app></c-test-app> になるので注意。

HTML は <template> を親として記述。JavaScript の変数は {name} みたいにして取り込む。
JavaScriptLightningElement 継承クラスを export default で返すことになる。
CSS は…まぁフツーに。強いていうと、ID 値は当てにならない。※

LWC のレンダリング結果は、基本的に LWC のフレームワークによる ShadowDOM の出力となる。よって、タグに ID 値を指定しても、実際には xxx-id みたいな謎のIDに置き換えられてしまうので、ID を使うことは実質できない。
また、普通の JavaScript のような DOM 操作は同じ理由からうまく動作しないので、行わない方が良い。

ライフサイクルとして

  • コンストラクタ: これ以上言うことなかろ?
  • connectedCallback DOMにこのコンポーネントが配置された際のイベント
  • renderedCallback 画面上に表示された
  • errorCallback(error, stack) 子・孫コンポーネントがエラーを吐いたときのコールバック
  • disconnectedCallback DOM から削除された

デコレータとして、LWCの独自デコレータがいくつかある。
OSS 版はまだしも、Salesforce 版のLWCはデコレータを自分で定義できません

  • @api LWC の外側から属性値として受け取れる変数へのデコレータ。getter/setter を指定できる。
  • @track プロパティに設定可能なデコレータで、指定された変数は中の { hoge: 'この値の変化' } とか [ '初期要素', '追加された要素' ] とかの中身まで監視される。
  • @wire Salesforce のいくつかのデータサービスを使って、SObject レコードを参照・操作できる。(※ ぶっちゃけ低性能なので、個人的にはApexの@AuraEnabled 推奨…ぶっちゃけゴミです)
続きを読む

Salesforce 開発者の JavaScript スキル(7)

Prepare for your Salesforce JavaScript Developer I Credential Trailmix の続き。

trailhead.salesforce.com

Develop the Gallery Component

ギャラリーコンポーネントを自作しよう。

自作とは名ばかりの追体験コーナー。
コレ の時に取ってきたコードの中から、PictureCarouselPictureGalleryCard をコピーして持ってこよう。

f:id:white-azalea:20211104221457p:plain

こんな感じになったら。

  • クラッチ組織作って
    sfdx force:org:create --setdefaultusername --setalias sfdx-maria --definitionfile config/project-scratch-def.json
  • push する
    sfdx force:source:push
  • サンプルデータを拾って
    sfdx force:data:tree:export --targetusername DevHub --outputdir assets/data --query "SELECT Id, Name, Email__c, Phone__c, Mobile_Phone__c, Title__c, Picture__c, ( SELECT Id, Address__c, Assessed_Value__c, Baths__c, Beds__c, Broker__c, City__c, Date_Agreement__c, Date_Closed__c, Date_Contracted__c, Date_Listed__c, Date_Pre_Market__c, Description__c, Location__Longitude__s, Location__Latitude__s, Picture__c, Price__c, Name, State__c, Status__c, Tags__c, Thumbnail__c, Title__c, Zip__c FROM Properties__r ) FROM Broker__c"
  • 権限セットを突っ込む
    sfdx force:user:permset:assign --permsetname DreamHouse
  • セットしたら、データをインポート
    sfdx force:data:tree:import -f assets/data/Broker__c-Property__c.json
  • Dream House 開いて
    f:id:white-azalea:20211104221927p:plain
  • 適当にプロパティを開く
    f:id:white-azalea:20211104222154p:plain
  • 開いたら「編集ページ」を開いて
    f:id:white-azalea:20211104222257p:plain
  • そしたらPictureGallery を配置して保存
    f:id:white-azalea:20211104222501p:plain
  • 出来上がりはこんな感じ
    f:id:white-azalea:20211104222626p:plain

因みに

  • テストは sfdx force:apex:test:run --codecoverage --resultformat human --wait 2
  • メタデータ取ってくるのは sfdx force:source:pull -f

後はコミット&push で git に記録しよう。

続きを読む

投資信託アプリアップデート

github.com

f:id:white-azalea:20211104211200p:plain

資産価値、損益並びにそのレートの表示を追加しました。
因みに表示されてるのは現在の自分の資産。

因みにこの資産は 11/4 時点で 7,224 円のプラスでした。

必ず儲かる保証はできませんが、銀行に預けておくよりまず間違いなくマシでしょう。
因みに銘柄見て「分散する意味なくない?」って感じのポートフォリオだと思った人、勉強してて良いですね!

7月から投資信託を始めていますが、銘柄や内容が違えど、全世界複数種に全米2種(片方はS&P)がメインです。
コモディティはネタで、たわらは気の迷いみたいなものです。

因みに、「たわら」はアクティブファンドで、かなりバランス型の配分を持つ銘柄なので、8月から投資して未だに 0.57% 増加という状況です。
9月の相場は大分乱れましたけど、最も減った時期ですら -1.09 % しか行きませんでした。どうしても減らしたくない代わりに、儲けもほとんどない…を許容するならアリですね。

これは本当に貯金と変わりませんね(汗

因みに NASDAQ100 もやりたくはあるんですが、ちょっと今バブリーな気配が漂ってて二の足踏んでます(汗
米国自体そろそろ調整入りそうなので、それを待って投資でしょうかね…

Salesforce 開発者の JavaScript スキル(6)

Prepare for your Salesforce JavaScript Developer I Credential Trailmix の続き。

trailhead.salesforce.com

要点だけ訳して切り抜くよシリーズ!

Create and Launch Your Trailhead Playground

Trailhead Playground を作成して起動する…
え?これ訳す意味ある?

ここクリックして f:id:white-azalea:20211021204004p:plain

「Playground を作成」クリックして f:id:white-azalea:20211021204045p:plain

分かりやすく名前つけてOK f:id:white-azalea:20211021204207p:plain

後は出来上がりをお待ちください f:id:white-azalea:20211021204350p:plain

Set Up Your Environment

環境をセットアップしよう
DreamHouse サンプルアプリを入れてみようという内容。

  1. さっき作ったPlaygroundを起動
  2. とりあえず英語化しませう(Trailhead だと大抵の場合で必須)
    f:id:white-azalea:20211021205209p:plain
  3. パッケージインストーラ
    f:id:white-azalea:20211021205334p:plain
  4. 04t3s000002qbLH を指定
    f:id:white-azalea:20211021205428p:plain
  5. Admin only でGO
    f:id:white-azalea:20211021205515p:plain
    因みにパッケージが見つからないなら https://login.salesforce.com/packaging/installPackage.apexp?p0=04t3s000002qbLH からインストールせーと言ってます
  6. 完了するとこうなるよ
    f:id:white-azalea:20211021205727p:plain

静的リソースから ExerciseFiles をDLして解凍
f:id:white-azalea:20211021205839p:plain

権限セットから DreamHouse > ManageAssignments で自分のアカウントに設定
f:id:white-azalea:20211021210251p:plain
f:id:white-azalea:20211021210434p:plain

そしたら DreamHouse 起動して
f:id:white-azalea:20211021210527p:plain

DataImport から設定をインストール
f:id:white-azalea:20211021210616p:plain

すると、サンプルデータ入ってるね?と
f:id:white-azalea:20211021210643p:plain

sfdx コマンドをアップデート (パッケージインストール派は sfdx update で、npm 派は npm install --global sfdx-cli)して、認証していきます。
この操作は こっち 参照。

続きを読む

Salesforce 開発者の JavaScript スキル(5)

trailhead.salesforce.com

Salesforce DX 環境の設定

  • クラッチ環境: SalesforceDX で操作するメインターゲット環境。短期間生存する環境を即興で作成、削除できる。
  • 開発者ハブ (Dev Hub) 組織 : スクラッチ環境を作成・管理する親組織

このハンズオンは スクラッチ組織作成機能を On にしてコンソールから接続するテスト。
尚、CLI 空の認証をするには、パスワード再発行手続きでブラウザからログインできるようにする必要あり。

DevHub 起動して f:id:white-azalea:20211020214512p:plain

パスワードリセットしときます f:id:white-azalea:20211020215612p:plain

接続時のコマンドは sfdx auth:web:login -d -a DevHub 名称は好きにして

ID/Pass を入力すると f:id:white-azalea:20211020220131p:plain

続きを読む