Keras 기반 확장성 사용
하지만 최근 둘러보니 케라스는 세계적으로 보급된 인터넷을 다른 프레임워크에 비해 희박하다는 답이 나왔다.다시 말하면 케라스의 확장성이 좋지 않다는 것이다.theano,tensorflow,torch,caffe 등 프레임워크를 시험적으로 사용한 적이 있는 사람으로서 나는 이것에 대해 그다지 동의하지 않는다.사실 Keras는 좋은 확장성을 가지고 있다. 이 부분은 디자인할 때 좋은 인터페이스를 남기기 때문이고, 다른 한편으로는 뚜렷한 코드 구조 때문에 사용자 정의 공간을 많이 가질 수 있다.그래서 다음은 몇 가지 예를 들어 Keras에서 층을 어떻게 사용자 정의하는지와 여러 가지 방법을 소개한다.
0、backend
Keras에서 다양한 레이어와 함수를 사용자 정의하려면 백엔드가 필요합니다.일반적으로 가져오는 방법은
from keras import backend as K
이것은 Keras가 두 가지 백그라운드, 즉 theano와tensorflow를 가질 수 있기 때문에 일부 조작 장량의 함수는 다음 데스크톱에 따라 다를 수 있다.이 백엔드를 도입하면 Keras가 호환성을 처리할 수 있습니다.
예를 들어 x의 평균을 구하면 K.mean(x)이다.backend 파일 자체는keras/backend 폴더에 있으며, 코드를 읽어서 backend가 어떤 조작을 지원하는지 알 수 있습니다.backend에는 함수가 많아서 일반적으로 모두 쓰기에 충분하다.
1. Lambda 레이어
만약 당신이 단지 이 층을 통과하는 데이터에 대해 변환을 하고 싶을 뿐, 이 변환 자체에 배울 매개 변수가 없다면, 직접 Lambda Layer를 사용하는 것이 가장 적합하다.
가져오는 방법은
from keras.layers.core import Lambda
Lambda 함수는 두 개의 매개 변수를 받아들인다. 첫 번째는 입력 장량이 출력 장량에 대한 映射 함수이고, 두 번째는 입력된 shape가 출력된 shape에 대한 映射 함수이다.예를 들어 이런 층을 구축하려면 이 층을 흐르는 데이터가 평균치를 빼면 다음과 같이 정의할 수 있다.
def sub_mean(x):
x -= K.mean(x,axis=1,keepdims=True)
return x
model.add( Lambda(sub_mean,output_shape=lambda input_shape:input_shape ))
출력된shape와 입력한shape는 같기 때문에 두 번째 파라미터는 항등영사를 직접 사용합니다.모형을 완전하게 세우다.
def get_submean_model():
model = Sequential()
model.add(Dense(5,input_dim=7))
def sub_mean(x):
x -= K.mean(x,axis=1,keepdims=True)
return x
model.add( Lambda(sub_mean,output_shape=lambda input_shape:input_shape))
model.compile(optimizer='rmsprop',loss='mse')
return model
model = get_submean_model()
res=model.predict(np.random.random((3,7)))
지res의 평균치는 [5.96046448e-08-5.96046448e-08 0.00000000e+00]로 균일치를 줄이는 작용을 확실히 실현했음을 알 수 있다.2. 비귀속층 사용자 정의
만약 자신이 정의하고 싶은 층에 학습이 필요한 변수가 있다면,lambda층을 사용할 수 없고, 스스로 하나 써야 한다.
예를 들어 나는 층을 정의하고 싶다. 그 효과는 장량에 대해 정대각진을 곱하는 것이다. (다시 말하면 입력 벡터는 배울 벡터와 원소를 곱하는 것이다.) 그러면 이렇게 쓸 수 있다.
먼저 기본 클래스 가져오기
from keras.engine.topology import Layer
그런 다음 MyLaber에 대해 다음과 같이 정의합니다.
class MyLayer(Layer):
def __init__(self,output_dim,**kw):
self.output_dim = output_dim
super(MyLayer,self).__init__(**kw)
def build(self,input_shape):
input_dim = input_shape[1]
assert(input_dim == self.output_dim)
inital_SCALER = np.ones((input_dim,))*1000
self.SCALER = K.variable(inital_SCALER)
self.trainable_weights = [self.SCALER]
super(MyLayer,self).build(input_shape)
def call(self,x,mask=None):
#return x - K.mean(x,axis=1,keepdims=True)
x *= self.SCALER
return x
def get_output_shape_for(self,input_shape):
return input_shape
주로 Keras에 내장된 층의 묘사법을 참조한다. 예를 들어 Dense는keras/layers/core에 있다.py에서 배울 수 있는 매개 변수를 self에 두어야 합니다.trainable_weights 중.여기에 초기치를 1000으로 설정한 것은 이 층의 효과를 더욱 뚜렷하게 하기 위해서이다.그리고 모형을 다 써서 테스트를 해보도록 하겠습니다.
def get_mylayer_model():
model = Sequential()
model.add(Dense(5,input_dim=7))
model.add(MyLayer(5))
model.compile(optimizer='rmsprop',loss='mse')
return model
model = get_mylayer_model()
res=model.predict(np.random.random((3,7)))
print res
res는 다음과 같습니다.[[ 271.2746582 -1053.31506348 147.17185974 -1120.33740234 609.54876709]
[ -263.69671631 -390.41921997 291.17721558 -594.58721924 615.97369385]
[ -46.58752823 -733.11328125 -21.9815979 -570.79351807 649.44158936]]
모두 큰 숫자입니다. MyLayer를 추가하지 않을 때 모든 값은 보통 +-2를 초과하지 않습니다. 이 층이 확실히 작용합니다.
fit 전에 모델을 호출합니다.get_weights (), 이 층의 권중은 모두 1000이다. 임의로 무작위로 테스트 집합이 나오고fit 수천 개의 epoch가 나온 후에loss는 매우 작아졌다. MyLayer의 권중은 997 정도가 되었고 앞의 Dense의 권중은 모두 10^-4 양급이 되었다. 이것은 MyLayer의 매개 변수도 확실히 배울 수 있다는 것을 의미한다.
3. 사용자 정의 손실 함수
Keras에 내장된 손실 함수는keras/objectives에 있습니다.py에서 예를 들어 mse의 정의는 다음과 같다.
def mean_squared_error(y_true, y_pred):
return K.mean(K.square(y_pred - y_true), axis=-1)
같은 형식에 따라 자신의 손실 함수를 정의할 수 있다.예를 들어 우리가 차액을 원하는 4차원의 평균을 손실 함수로 한다.
def my_object(y_true,y_pred):
return K.mean(K.square(K.square(y_pred-y_true)),axis=-1)
모형을 모두 쓰기:
def get_myobj_model():
model = Sequential()
model.add(Dense(5,input_dim=7))
model.add(Dense(3))
def my_object(y_true,y_pred):
return K.mean(K.square(K.square(y_pred-y_true)),axis=-1)
model.compile(optimizer='sgd',loss=my_object)
return model
model = get_myobj_model()
손실 함수를 사용자 정의할 수 있는 것은 매우 중요한 일환으로, 네트워크의 응용을 크게 확장시켰다.예를 들어 cnn으로 전후경 분할을 훈련하고자 하는 필터는 출력된 픽셀이 전경에 대응하는 위치는 1이고 후경에 대응하는 위치는 0이다.네트워크 출력의 값이 mse가 작기를 바랄 뿐만 아니라, 0과 1이 각각 연결되어 눈꽃 모양의 출력이 나오지 않기를 바랍니다.그러면 사용자 정의 손실 함수는 할 수 있다. 실제적으로 두 개의 손실 함수를 하나의 손실 함수에 넣었다.또 다른 유용한 손실 함수, 예를 들어warp-ctc는 여기에 모형을 집적할 수 있다.
4. 사용자 정의 귀속층
귀속층의 정의 방법은 비귀속층과 그다지 다르다.Keras 내 LSTM에 따르면 reset_states 함수와 step 함수, 이것은 귀속의 성질에 의해 결정된다.예는 모두keras/layers/recurrent에 있습니다.py 중.
전에 선배가 lasagne로 쓴 LSTM의 변체를 보고 울고 싶었는데 차라리 케라스에서 LSTM 코드를 복사해서 수정하는 게 낫겠다.그러나 LSTM도 직접 복제할 수 없고 import의 몇 가지 의존도가 필요합니다.
rom keras.layers.recurrent import LSTM,Recurrent,time_distributed_dense
from keras import initializations,regularizers,activations
from keras.engine import InputSpec
5. 사용자 정의 최적화 함수
Keras의 코드는 확실히 좋고 결합도가 매우 낮다.Keras에 내장된 최적화 함수는keras/optimizers에 있습니다.py에서 기본 Optimizer도 이 파일에 있습니다.예를 들어 그것에 내장된 SGD 알고리즘을 자신의 파일에 복사하는 경우, 먼저fromkeras.optimizers import Optimizer를 통해 컴파일할 수 있습니다.
때때로state-of-the-art의 결과를 얻으려면 sgd 가동량법으로 충분히 수렴해야 한다.예를 들어 학습률 0.01에 100epoch를 배우고 학습률을 반으로 줄이고 100epoch를 배우고 순서대로 유추한다.최적화 함수를 사용자 정의하지 않으면fit 함수를 단계별로 호출하여 학습률을 수정하고 다시 컴파일해야 할 수도 있습니다.이것은 그다지 아름답지 않다.다른 진기한 학습 전략도 사용자 정의 최적화 함수를 통해 얻을 수 있다.
후기
Keras는 정말 강력해서 큰 숙제를 할 수 있을 뿐만 아니라 연구를 해도 충분하다.Yeah
추가:keras의 확장성:사용자 정의keras
1. 사용자 정의 keras
keras는 딥러닝 API로 당신의 실험을 신속하게 실현할 수 있습니다.keras도 많은 예비 훈련 모델을 통합하여 이미지 분류와 같은 일반적인 임무를 실현할 수 있다.텐서 플로우 2.0 이후 텐서 플로우 자체도 keras화되었다.
다른 한편,keras는 고도의 모듈화와 봉인성을 나타내기 때문에 어떤 사람들은 keras가 확장하기 어렵다고 느낀다. 예를 들어 새로운 Loss, 새로운 네트워크 층 구조를 실현하는 것이다.사실keras의 기초 모듈을 통해 신속하게 확장하여 업데이트된 알고리즘을 실현할 수 있다.
본고는keras의 확장성에 대해layer,model,loss에 대한 사용자 정의를 총괄하였다.
2. 사용자 정의keras layers
layers는keras의 중요한 구성 부분으로 네트워크 구조의 모든 구성은layers로 표현해야 한다.convolutionlayers,poolinglayers,activationlayers,denselayers 등 일반적인 레이어를 많이 제공합니다. 우리는 기초 레이어를 계승하여 사용자 정의layers를 확장할 수 있습니다.
2.1 base layer
layer는tensor를 입력하고 출력하는tensor의 작업 클래스를 구현하였습니다. 다음은baselayer의 5가지 방법입니다. 사용자 정의layer는 이 방법들을 다시 쓰기만 하면 됩니다.
init (): 사용자 정의layer의 속성 정의
build(self, input_shape):layer에 필요한 가중치 정의weights
call(self, *args, *kwargs):layer의 구체적인 조작은 사용자 정의layer를 호출하여 자동으로 실행됩니다
get_config(self):layer 초기화 설정은 사전dictionary입니다.
compute_output_shape(self, input_shape): tensor를 출력하는 shape를 계산합니다.
2.2 예
#
class InstanceNormalize(Layer):
def __init__(self, **kwargs):
super(InstanceNormalize, self).__init__(**kwargs)
self.epsilon = 1e-3
def call(self, x, mask=None):
mean, var = tf.nn.moments(x, [1, 2], keep_dims=True)
return tf.div(tf.subtract(x, mean), tf.sqrt(tf.add(var, self.epsilon)))
def compute_output_shape(self,input_shape):
return input_shape
#
inputs = keras.Input(shape=(None, None, 3))
x = InstanceNormalize()(inputs)
# add_weight()
class SimpleDense(Layer):
def __init__(self, units=32):
super(SimpleDense, self).__init__()
self.units = units
def build(self, input_shape):
self.w = self.add_weight(shape=(input_shape[-1], self.units),
initializer='random_normal',
trainable=True)
self.b = self.add_weight(shape=(self.units,),
initializer='random_normal',
trainable=True)
def call(self, inputs):
return tf.matmul(inputs, self.w) + self.b
#
inputs = keras.Input(shape=(None, None, 3))
x = SimpleDense(units=64)(inputs)
3. 사용자 정의keras 모델
우리는 네트워크 구조를 정의할 때 전체 작업 흐름을keras에 놓을 것이다.모델, compile () 을 하고fit () 를 통해 훈련 과정을 진행한다.fit()를 실행할 때, 모든 batch size 데이터를 실행할 때, 모델의train_step(self, data)
from keras.models import Sequential
from keras.layers import Dense, Activation
model = Sequential()
model.add(Dense(units=64, input_dim=100))
model.add(Activation("relu"))
model.add(Dense(units=10))
model.add(Activation("softmax"))
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5, batch_size=32)
훈련 과정을 스스로 컨트롤해야 할 때 모델의train_step(self,data) 방법
class CustomModel(keras.Model):
def train_step(self, data):
# Unpack the data. Its structure depends on your model and
# on what you pass to `fit()`.
x, y = data
with tf.GradientTape() as tape:
y_pred = self(x, training=True) # Forward pass
# Compute the loss value
# (the loss function is configured in `compile()`)
loss = self.compiled_loss(y, y_pred, regularization_losses=self.losses)
# Compute gradients
trainable_vars = self.trainable_variables
gradients = tape.gradient(loss, trainable_vars)
# Update weights
self.optimizer.apply_gradients(zip(gradients, trainable_vars))
# Update metrics (includes the metric that tracks the loss)
self.compiled_metrics.update_state(y, y_pred)
# Return a dict mapping metric names to current value
return {m.name: m.result() for m in self.metrics}
import numpy as np
# Construct and compile an instance of CustomModel
inputs = keras.Input(shape=(32,))
outputs = keras.layers.Dense(1)(inputs)
model = CustomModel(inputs, outputs)
model.compile(optimizer="adam", loss="mse", metrics=["mae"])
# Just use `fit` as usual
x = np.random.random((1000, 32))
y = np.random.random((1000, 1))
model.fit(x, y, epochs=3)
4. 사용자 정의keras loss
keras는 교차 엔트로피 등 흔히 볼 수 있는loss를 실현했다. 사용자 정의loss는keras를 사용하는 데 있어 비교적 흔하고 각종 마개loss, 예를 들어focalloss를 실현한다.
케라스 원본 코드에서 로스에 대한 실현을 봅시다.
def categorical_crossentropy(y_true, y_pred):
return K.categorical_crossentropy(y_true, y_pred)
def mean_squared_error(y_true, y_pred):
return K.mean(K.square(y_pred - y_true), axis=-1)
입력이 groud true y_임을 알 수 있습니다.true 및 예측 y_pred, 로스를 계산하는 함수로 되돌려줍니다.사용자 정의loss는 이 모드를 참조하면 됩니다.
def focal_loss(weights=None, alpha=0.25, gamma=2):
r"""Compute focal loss for predictions.
Multi-labels Focal loss formula:
FL = -alpha * (z-p)^gamma * log(p) -(1-alpha) * p^gamma * log(1-p)
,which alpha = 0.25, gamma = 2, p = sigmoid(x), z = target_tensor.
# https://github.com/ailias/Focal-Loss-implement-on-Tensorflow/blob/master/focal_loss.py
Args:
prediction_tensor: A float tensor of shape [batch_size, num_anchors,
num_classes] representing the predicted logits for each class
target_tensor: A float tensor of shape [batch_size, num_anchors,
num_classes] representing one-hot encoded classification targets
weights: A float tensor of shape [batch_size, num_anchors]
alpha: A scalar tensor for focal loss alpha hyper-parameter
gamma: A scalar tensor for focal loss gamma hyper-parameter
Returns:
loss: A (scalar) tensor representing the value of the loss function
"""
def _custom_loss(y_true, y_pred):
sigmoid_p = tf.nn.sigmoid(y_pred)
zeros = array_ops.zeros_like(sigmoid_p, dtype=sigmoid_p.dtype)
# For poitive prediction, only need consider front part loss, back part is 0;
# target_tensor > zeros <=> z=1, so poitive coefficient = z - p.
pos_p_sub = array_ops.where(y_true > zeros, y_true - sigmoid_p, zeros)
# For negative prediction, only need consider back part loss, front part is 0;
# target_tensor > zeros <=> z=1, so negative coefficient = 0.
neg_p_sub = array_ops.where(y_true > zeros, zeros, sigmoid_p)
per_entry_cross_ent = - alpha * (pos_p_sub ** gamma) * tf.log(tf.clip_by_value(sigmoid_p, 1e-8, 1.0)) \
- (1 - alpha) * (neg_p_sub ** gamma) * tf.log(
tf.clip_by_value(1.0 - sigmoid_p, 1e-8, 1.0))
return tf.reduce_sum(per_entry_cross_ent)
return _custom_loss
5. 요약
본고는keras의 확장 기능을 공유했는데 확장 기능도 사실은 Keras 모듈화를 실현하는 일종의 계승 실현이다.
요약은 다음과 같습니다.
레이어를 계승하여 사용자 정의layer를 구현하고 bulid()call()을 기억하십시오
계속 Model 구현 train_step는 훈련 과정을 정의하고 사다리 계산tape를 기억합니다.gradient(loss,trainable_vars),optimizer를 다시 업데이트합니다.apply_gradients, 계산 evaluate compiled_metrics.update_state(y, y_pred)
마개로스, groud true y_ 기억하기true 및 예측 y_pred 입력,loss function 반환
이상의 개인적인 경험으로 여러분께 참고가 되었으면 좋겠습니다. 또한 많은 응원 부탁드립니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
TensorFlow+Keras로 Cutout 구현/평가에서 각종 Data Augmentation을 구현했을 때, TensorFlow Addons를 사용하면 간단하게 Cutout을 구현할 수 있는 것을 깨달았다. 여기에서는 Dataset에 대해서 map 적용하는 구현과 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.