技術をかじる猫

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

書籍レビュー:ジェイソン流お金のお増やし方

紹介する書籍

ざっくり書評

投資未経験者~中級者まで楽しく読める投資入門書。
(自分は上級では無いので、おそらく中級)

約15年間投資を続けたことで、FIRE を既に達成している人物による投資の経験本。
感覚的に日本人に非常に合う投資方法(リスクとしては低での投資)を行っていることもあり、コレを真似るだけで十分再現できそうな内容。

見どころ

  • ジェイソン氏が金持ちになった方法≒おすすめの方法
  • 達成するための価値観、考え方
  • 死ぬほどやってることはシンプル(これで駄目ならどんな投資本見ても無駄!)

それ故に日本人の殆どが全てでないにせよ、それなりに貯蓄を作ることができます。

尚、海外投資で「アセットアロケーション」とか「リスク許容度」等銘柄を選ぶ上で必要な判断基準用語には触れません。
なので銘柄を自分で判断する場合の考え方…などを学ぶには少々難しいかもしれません。
とはいえ、初心者向けならそんな事せずにとりあえず「VTIにぶっこんどけ!」で良いのかもしれません。(汗

ざっくり内容

ジェイソン流の投資方法は以下の通り

  1. まずは節約しよう
  2. 節約で浮いた金を 3 ヶ月分の生活費を残して全部投資にぶっこむ
  3. 投資は ティッカーシンボル*1「VTI *2」に全力投資。
  4. 売らずにガチ保持

これだけ!というかコレが全部と言っていいです。
具体的やり方…という目次とその概要。

各章のざっくり

尚、2章+3章で本 7 割を占めるという…

*1:株やETF等を示す略称。

*2:Vanguard Total Stock Market Index Fund ETF。全米株の詰め合わせセットだと思えばよろしい

続きを読む

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

Prepare for your Salesforce JavaScript Developer I Credential Trailmix

コレの続き。

Lightning Web コンポーネントSalesforce データ

Lightning データサービスを使用したデータの操作

trailhead.salesforce.com

まぁ単純に作る系のお話。

  • LWC(Name: ContactCreator) 作って
  • コンポーネントではオブジェクトとフィールド名を用意。保存完了時に toast (画面↑に緑の帯で出るメッセージ)表示

オブジェクトのフィールド定義系

// Object
import CONTACT_OBJECT from '@salesforce/schema/Contact';
// Fields
import FIRST_NAME_FIELD from '@salesforce/schema/Contact.FirstName';
import LAST_NAME_FIELD from '@salesforce/schema/Contact.LastName';
import EMAIL_FIELD from '@salesforce/schema/Contact.Email';

// 中略
    objectApiName = CONTACT_OBJECT;
    fields = [FIRST_NAME_FIELD, LAST_NAME_FIELD, EMAIL_FIELD];
  • 保存成功時は toast で表示する
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

// 中略
    handleSuccess(event) {
        const toastEvent = new ShowToastEvent({
            title: "Account created",
            message: "Record ID: " + event.detail.id,
            variant: "success"
        });
        this.dispatchEvent(toastEvent);
    }
        <lightning-record-form
            object-api-name={objectApiName}
            fields={fields}
            onsuccess={handleSuccess}>
        </lightning-record-form>
  • 最後に Lightning App Builder で登録できるようにして登録
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target><!-- アプリケーションページで使いますよー宣言 -->
    </targets>
</LightningComponentBundle>

ちなみに、これで一旦レコード作ってしまうと、再編集しても保存後の表示が変わらない…
キャッシュ機構があると思われるので、

refreshValues() {
    const inputFields = this.template.querySelectorAll('lightning-input-field');
    if (inputFields) {
        inputFields.forEach((field) => {
            field.reset();
        });
    }
}

で強制的にリフレッシュしてもいいし、レコード状態が変化したことを Salesforce経由で通知 してもいい

続きを読む

DeepLearning 生成させる学習方法

RNN(LSTM/GRU) 等

時系列のデータを扱うタイプの DeepLearning.

画像であれば、画像のY軸を時系列データと想定して、残りを予測させるといったやり方で画像を作成できるっぽい。
要するにどのように時系列データとして食わせるかで次の値を予測させるというもののようだ。

単純に手書き数字の上半分だけ食わせて、下半分を予測させるとこんな感じで生成された。

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

2,3,8 は上半分の形状が似ているせいでよくわからないことになってしまった。
8, 7 は学習データがそもそも悪いwww
5, 6 は混ざって学習したんじゃないかという予想。
9 は上半分で切ったとき微妙に2に混ざったかなにかしたかなという印象。

時系列情報から次の値を予測させるという意味では、やはり先頭部分の情報ありきだ。
キモは「どのように時系列のデータに見立てるか」だと思われる。

尚、翻訳などにはこれを利用した Seq2Seq (Sequence to Sequence。Sequence という系列情報を認識して別の系列に変換する) というアルゴリズムを使っていて、この根底も RNN を使っていくそうな。
ぱっと見た感じ、形態素解析した上でRNNに食わせて変換しているっぽい。

CNN

認識・判定用

これは画像などの認識を行うニューラルネット
映像判定とか顔判定等をメインに扱うものなので、極論すると生成には向かないと思われる。

単純な入力→出力型DeepLearning

下書きを読み込んで線画にするAIは予測系ではなくて単純に入力→結果対応をしてると思う。
画像を行列にして食わせて、線画の結果を取得する。

色を付けるのも多分似たようなものかもしれない。

ただしサンプルは相当な量が必要だし、画像となれば学習時間もエグい事になりそう…
ちょっと個人で手が出るものでは無いと思われる。

VAE (Variational Autoencoder)

画像などから特徴情報に変換(Encoder。特徴抽出と圧縮)し、中間集中力(この値を「潜在変数」と呼び、)その特徴情報から出力(Decoder)の二段回の変換を行うニューラルネット
潜在変数値は元の情報より圧縮されてる。教師なし学習に分類されるご様子。

主に、入力と出力の差分を取ることで異常値を検出できる。

で、この時潜在変数を任意にイジってやることで、全く新しい画像を自動生成できるということらしい。
派生で Conditional VAE (潜在変数の他に、ラベルパラメータを指定することで、生成するデータのカテゴリを指定できるようにしたVAE)。
β-VAE (複数要素を含む情報を処理できるVAE)Vector Quantised-VAE (潜在変数が特徴を捉えきれなかった場合にボケる等が発生する問題に対処したVAE。潜在変数を離散値で扱う) Vector Quantised-VAE2 (Vector Quantised-VAE を階層構造にすることで、高解像度の生成を行えるようにしたもの)

GAN (Generative Adversarial Networks)

敵対的生成ネットワーク。
Generator (ランダムなノイズから、偽データを生成するNN)と、Descriminator(偽データと本物のデータを見て真贋判定するNN)の2つで競わせるニューラルネットワーク
完全に新しい画像等を生成するのに用いる。

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

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

trailhead.salesforce.com

また来たよ英語回

Get Started with Lightning Development

Lightning 開発を始めよう

Get Started with Lightning Development 単元 | Salesforce Trailhead

VF 使いのためのLightning入門記事ですね。
VF は 2006 年以前に、エンタープライズ・ソリューションとして作成され、サーバサイド動作として作られた。
2006 年以降、インタラクティブ、動的、レスポンシブなデザインに切り替わってきていて、Salesforce としては Lightning Experience として Lightning component フレームワークを作成した。

  • コンポーネントあはSalesforce内で再利用可能
  • アプリケーション機能を容易に拡張できる
  • AppExchange からカスタムコンポーネントをDLして開発できる
  • モバイル機器に最適化したレスポンシブデザインの開発を開発者に提供する
  • ベースコンポーネントは非常に多くの機器で動作する

あと、Low-Code と Pro-Code でカテゴリ分けてる。

  • Low-Code : クリックベースで開発できるやつ(フローとか、クイックアクション、URLボタンなど)
  • Pro-Code : プログラミングして開発するやつ

Learn How Coding Concepts Apply to Lightning Web Components

LWC ではどのような開発コンセプトが適用されているか学習する

Learn How Coding Concepts Apply to Lightning Web Components 単元 |

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

まぁ見たままだよね。
サーバサイドではデータの管理だけしてて、HTML 表示などは全てクライアントで行う。
OSS の世界で言うなら、 MVVM といったところ。

  • Tracking State with Properties : プロパティの更新をトラッキングする。
    OSS で開発してる人なら「変数バインド」といえばいいか。VF 使いなら {! 変数 }{変数} になるといえばわかるはず。
  • Tracking State with Getters and Setters : Getter/Setter の状態をトラッキングする。
    実質変数に近い扱いでバインドできる。
    get hoge() { return this._hoge; }
    set hoge(v) { this._hoge = v; }
    <template>{hoge}</template>
<template>
    <template if:true={areDetailsVisible}>
        These are the details!
    </template>
</template>
<template>
    <template for:each={contacts} for:item="contact">
        <p key={contact.Id}>
            {contact.Name}
        </p>
    </template>
</template>
  • イベントハンドリング
<template>
    <a onclick={handleButtonClick}></a>
</template>
    handleButtonClick(e) {
        window.console.log(e); // イベントの表示
    }

標準コンポーネントとか ここ 見るといいかも

問題の傾向
* LWC は何をきっかけに再レンダリングされる?→プロパティ変更を参照して * コンポーネントは親コンポーネントにどうやって情報を送る?→イベントだよね

続きを読む

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 推奨…ぶっちゃけゴミです)
続きを読む