Hy로 Rescale에서 Keras를 사용하는 신경망

오랫동안 GNU Emacs 사용자님, 제가 데리러 왔습니다 C-x C-e (eval-last-sexp) 당연합니다. 즉, 제가 편집하고 있는 거의 모든 파일에서 어디에 있든 괄호 표현식을 삽입할 수 있습니다. C-x C-e, 미니버퍼에 결과가 표시됩니다(또는 lisp로 프로그래밍하는 경우 REPL에서).
다른 많은 언어는 콘솔 인터페이스 또는 REPL을 제공하지만 일반적으로 REPL이 아닌 언어의 별도 기능으로 제공됩니다. 꾸민 상호 작용 모드. 이것이 피상적인 관찰이라는 점은 인정하지만 사용자 상호 작용에 대한 "스크립트 중심" 또는 "REPL 중심" 접근 방식이라는 용어를 재구성할 수 있습니다. 새로운 프로그래밍 언어를 배우고 있다고 상상해 보십시오. "스크립트 중심" 접근 방식은 터미널(또는 IDE)에서 hello world 프로그램을 실행하는 방법을 신속하게 소개하는 반면, "REPL 중심" 접근 방식은 REPL에 참여하고 필요한 표현식을 평가하는 방법을 신속하게 소개합니다. Hello World 효과를 달성하세요.
즉, "스크립트 중심" 접근 방식은 개념적으로 편집 및 평가 주기를 분리하는 반면, "REPL 중심" 접근 방식은 표현, 평가 및 피드백의 단일 흐름을 중심으로 설계되었습니다. 각 방법에는 장단점이 있지만 프로토타입화 및 실험의 경우 커서에서 바로 코드를 평가하는 것에서 "코드와 함께 있는" 느낌을 받기가 어렵습니다. Emacs에서 lisp 계열 언어의 경우 이는 일반적으로 예상되는 상호 작용 방법입니다.
이것을 어떻게 증명할 수 있을까요? 음, 내 동료 마크 튜토리얼을 작성했습니다 XNUMX월에 Keras 학습 작업을 설정하는 방법에 대해 알아봤습니다. 그 이후로 소프트웨어가 업데이트되었으므로 해당 작업의 업데이트된 버전을 생성하겠습니다. 하지만 원시 Python 대신에 우리는 하일랑, 이는 기본적으로 Python 인터프리터용 lisp.

Emacs와 함께 최신 버전의 Emacs(예: 버전 24 이상)를 실행하고 있다고 가정합니다. 패키지 관리자 설정, 당신은 설치하고 싶을 것입니다 하이 모드 (M-x package-install RET hy-mode RET) 그리고 많은 lispy paren 패키지 중 하나입니다. 예: 패러디, 스마트파렌스, 리스피.
새 파일에서는 cifar10_cnn.hy, 현재 켜져 있는지 확인하세요 Hy 방법. 그런 다음 사용 M-x inferior-lisp hy repl을 시작하려면! Emacs 상호 작용에 대한 비디오 데모를 보려면 아래로 스크롤하십시오.

1. 먼저 수입품부터 처리하자 

1.1 파이썬

from __future__ import print_function from keras.datasets import cifar10 from keras.models import Sequential from keras.layers.core import Dense, Dropout, Activation, Flatten from keras.layers.convolutional import Convolution2D, MaxPooling2D from keras.optimizers import SGD, Adadelta, Adagrad keras.utils import np_utils, six.moves 가져오기 범위의 generic_utils

1.2 이것을 hy로 다시 작성:

(import [__future__ [print_function]] [keras.datasets [cifar10]] [keras.models [Sequential]] [keras.layers.core [Dense Dropout Activation Flatten]] [keras.layers.convolutional [Convolution2D MaxPooling2D]] [keras .optimizers [SGD Adadelta Adagrad]] [keras.utils [np_utils generic_utils]] [six.moves [범위]] [numpy :as np])

51단어 ~ 39단어. 간결함에 있어서 나쁘지 않아요!

2. 그런 다음 상수를 다시 작성해 보겠습니다.

2.1 파이썬

배치_크기 = 32 nb_classes = 10 nb_epoch = 100 # 입력 이미지 크기 img_rows, img_cols = 32, 32 # CIFAR10 이미지는 RGB입니다 img_channels = 3

2.2 하이

(def 배치_크기 32 nb_classes 10 nb_epoch 100 ;; 입력 이미지 크기 img_rows 32 img_cols 32 ;; CIFAR10 이미지는 RGB img_channels 3입니다)

Hylang은 다음에서 영감을 얻습니다. Clojure, 그러나 Clojure와는 달리 여러 변수를 허용합니다. def-s는 기본값입니다. 이런 경우에는 꽤 편리합니다.

3. 기능

Note that the input_shape 이전 버전 이후 인수 순서가 변경되었습니다. (channels, rows, columns)(rows, columns, channels)

3.1 파이썬

def load_dataset(): # 훈련 세트와 테스트 세트 사이에서 섞이고 분할된 데이터 (X_train, y_train), (X_test, y_test) = cifar10.load_data() print('X_train shape:', X_train.shape) print(X_train. Shape[0], 'train Samples') print(X_test.shape[0], 'test Samples') # 클래스 벡터를 이진 클래스 행렬로 변환 Y_train = np_utils.to_categorical(y_train, nb_classes) Y_test = np_utils.to_categorical(y_test, nb_classes) X_train = X_train.astype('float32') X_test = X_test.astype('float32') X_train /= 255 X_test /= 255 return X_train, Y_train, X_test, Y_test def make_network(): model = Sequential() 모델. add(Convolution2D(32, 3, 3, border_mode='same', input_shape=(img_rows, img_cols, img_channels))) model.add(Activation('relu')) model.add(Convolution2D(32, 3, 3) ) model.add(활성화('relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Convolution2D(64, 3, 3, border_mode= '동일')) model.add(Activation('relu')) model.add(Convolution2D(64, 3, 3)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(2 , 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dropout(0.5) ) model.add(Dense(nb_classes)) model.add(Activation('softmax')) 반환 모델 def train_model(model, X_train, Y_train, X_test, Y_test): sgd = SGD(lr=0.01,decay=1e-6 , 모멘텀=0.9, 네스테로프=True) model.compile(loss='categorical_crossentropy', 옵티마이저=sgd) model.fit(X_train, Y_train, nb_epoch=nb_epoch, 배치_크기=batch_size, 유효성 검사_split=0.1, show_accuracy=True, verbose=1 ) print('테스트 중...') res = model.evaluate(X_test, Y_test, 배치_크기=batch_size, verbose=1, show_accuracy=True) print('테스트 정확도: {0}'.format(res[1]) ) def save_model(모델): model_json = model.to_json() open('cifar10_architecture.json', 'w').write(model_json) model.save_weights('cifar10_weights.h5', overwrite=True)

3.2 하이

아래 코드에서 우리는 변수 구조화를 작성할 수 있습니다. TRAINTEST 다음과 같이 한 단계만 거치면:
(let [ [[X-train y-train] [X-test y-test]] (cifar10.load_data) ] )

 

(defn load-dataset [] ;; 훈련 세트와 테스트 세트 간에 섞이고 분할된 데이터([[TRAIN TEST] (cifar10.load_data) [X-train y-train] TRAIN [X-test y-test] TEST ;; 클래스 벡터를 이진 클래스 행렬로 변환 Y-train (np_utils.to_categorical y-train nb_classes) Y-test (np_utils.to_categorical y-test nb_classes)] (인쇄 "OK") (인쇄 "X_train 모양: " X-train .shape) (인쇄 (X-train.shape 0 가져오기) "트레인 샘플") (인쇄 (X-test.shape 0 가져오기) "테스트 샘플") ;; 하이 튜플 표기법 (, X-train Y-train X- 테스트 Y-테스트))) (defn make-network [] (doto (순차) (.add (Convolution2D 32 3 3 :border_mode "same" :input_shape (, img_rows img_cols img_channels))) (.add (활성화 "relu" )) (.add (Convolution2D 32 3 3)) (.add (활성화 "relu")) (.add (MaxPooling2D :pool_size (, 2 2))) (.add (드롭아웃 0.25)) (.add (Convolution2D 64 3 3 :border_mode "동일")) (.add (활성화 "relu")) (.add (Convolution2D 64 3 3)) (.add (활성화 "relu")) (.add (MaxPooling2D :pool_size (, 2 2 ))) (.add(드롭아웃 0.25)) (.add(평탄화)) (.add(밀도 512)) (.add(활성화 "relu")) (.add(드롭아웃 0.5)) (.add(밀도 nb_classes )) (.add (활성화 "softmax")))) (defn train-model [모델 X-train Y-train X-test Y-test] (let [sgd (SGD :lr 0.01 :decay 1e-6 :momentum) 0.9 :nesterov true)] (doto 모델 (.compile :loss "categorical_crossentropy" :optimizer sgd) (.fit X-train Y-train :nb_epoch nb_epoch :batch_size 배치_크기 :validation_split 0.1 :show_accuracy true :verbose 1))) (인쇄 "테스트 중...") (let [res (model.evaluate X-test Y-test :batch_size 배치_크기 :verbose 1 :show_accuracy true)] (-> "테스트 정확도 {}" (.format (res 1 가져오기)) (인쇄)))) (defn save-model [model] (with [ofile (open "cifar10_architecture.json" "w")] (ofile.write (model.to_json))) (model.save_weights "cifar10_weights.h5" : 덮어쓰기 참))

사용 방법에 주목하세요 doto 여기서는 반복 할당을 정말 단순화합니다. 표현식은 내부의 최종 형식으로 평가되므로 doto, 우리의 모델 설정 make-network 변수 이름도 필요하지 않습니다.
Hylang은 편리한 스레딩 매크로(->)도 지원합니다. 클로저, 이를 통해 명령문을 쉽게 연결할 수 있습니다. 이 예에서는 형식 문자열을 .format 기능을 수행한 다음 인쇄하세요.

4. 메인 런너 블록

4.1 파이썬

if __name__ == '__main__': X_train, Y_train, X_test, Y_test = load_dataset() model = make_network() train_model(model, X_train, Y_train, X_test, Y_test) save_model(모델)

4.2 하이

(when (= --name-- "__main__") ;; 재현성을 위해 추가됨 (np.random.seed 1) (let [[X-train Y-train X-test Y-test] (load-dataset)] ( doto (make-network) (train-model X-train Y-train X-test Y-test) (save-model))))

5. 빠른 비디오

이 짧은 비디오에서 결과를 로드하는 방법을 볼 수 있습니다. hylang 파일을 emacs에 저장하고 hy REPL을 통해 실행하여 해당 구문을 평가합니다(다음과 같이 표시됨). ^X ^E 키 오버레이에서), 그렇지 않으면 REPL과 편집 버퍼 사이를 앞뒤로 전환합니다.
마지막에 보면 내가 얼마나 놓쳤는지 알 수 있어 numpy 가져오기, 가져오기를 (import ...) 양식을 작성하고 전체 가져오기 양식을 재평가했습니다. 커서를 양식 끝으로 이동하여 사용했습니다. eval-last-sexp표현식을 평가하기 위해 다음을 사용할 수도 있었습니다. Ctrl Alt x or lisp-eval-defun, 커서 주변의 최상위 표현식을 평가합니다.
이후 load-datasetmake-network 인수를 사용하지 않으면 함수 본문을 다음과 같이 래핑하는 것이 편리합니다. let or doto 표현(또는 형태), 해당 지점에서 블록을 반복적으로 평가하고, REPL 출력을 확인하고, 만족되면 래핑합니다. let 차단하다 defn 양식.

6. 플랫폼에서 실행하기

내 컴퓨터에 GPU 성능이 좋지 않아 훈련 시간이 오래 걸리기 때문에 실제 모델 훈련을 시작하자마자 비디오가 멈춥니다. 따라서 대신 Rescale 플랫폼에 다시 설치하여 완료하고 먼저 hy 실행하여 컴파일러

 

pip 설치 git+https://github.com/hylang/hy.git

그런 다음 단순히 전화 hy cifar10_cnn.hy Mark의 이전 예제 출력을 복제합니다.
(이 예에서는 GitHub에서 직접 hylang의 최신 버전(버전 0.11.0, 커밋 0abc218)을 실행하고 있습니다.) 다음을 사용하여 hy를 설치한 경우 pip install hy 이전 과제를 사용하고 있을 수 있습니다. let/with 통사론.
바로 실행 가능한 예제를 찾을 수 있습니다. 여기에서 지금 확인해 보세요.. 또한 이 게시물의 유형 버전도 찾을 수 있습니다. github에서.

7. 말장난을 용서하세요

그런데 이제 때가 됐나? 보시다시피 Emacs에 대한 REPL 통합에는 단점이 있습니다. 심층 스택 추적에서 오류를 디버깅하는 것도 성숙한 디버깅 도구의 지원이 적기 때문에 조금 더 어렵습니다. 그러나 Lisp 작업을 즐기고 Python 생태계에서 작업하기를 원하거나 필요하다면 hy는 웹 개발, 기계 학습 또는 일반 텍스트 구문 분석에 사용할 수 있는 기능적이고 강력하며 즐거운 도구입니다. 믹스 앤 매치도 가능하다고 말씀드렸나요? hy 파일과 py 파일?

비슷한 게시물