Keras 스타일 이전 실현
스타일 이전 알고리즘 은 여러 차례 정의 와 업 데 이 트 를 거 쳐 현재 많은 스마트 폰 앱 에 응용 되 고 있다.스타일 이전 은 목표 이미지 내용 을 유지 하 는 토대 에서 이미지 스타일 을 목표 이미지 에 참조 합 니 다.스타일 은 본질 적 으로 각종 공간 척도 에서 이미지 의 무늬, 색채 와 시각 도안 을 말한다.내용 은 이미지 의 고급 거시적인 구조 이다.스타일 이전 뒤의 관건 적 인 개념 은 모든 깊이 있 는 학습 알고리즘 의 핵심 과 같다. 손실 함 수 를 정의 하여 실현 하고 자 하 는 목 표를 지정 하고 이런 손실 을 최대한 줄인다.자신 이 실현 하고 자 하 는 목 표를 알 고 있 습 니 다. 이미지 의 스타일 을 참고 하 는 동시에 원본 이미지 의 내용 을 보존 합 니 다.만약 우리 가 수학 적 으로 내용 과 스타일 을 정의 할 수 있다 면, 최소 화 된 적당 한 손실 함 수 는 다음 과 같은 내용 입 니 다: loss = distance (style (reference image) - style (generated image) + distance (content (original image) - content (generated image)
distance 는 L2 범 수의 함수 로 content 가 그림 내용 을 계산 하여 표시 하 는 함수 입 니 다.style 그림 스타일 표시 함수 계산.손실 함수 최소 화 는 style (generated image) 과 참조 이미지 style (reference image) 을 가능 한 한 접근 시 키 고, content (generated image) 는 콘 텐 츠 이미지 content (original image) 와 가능 한 한 접근 하여 스타일 이전 목 표를 달성 합 니 다.
내용 손실 함수
우 리 는 네트워크 모델 앞의 몇 층 의 활성화 함수 값 이 그림 의 국부 정 보 를 나타 내 는 것 을 이미 알 고 있다. 고 층 네트워크 활성화 값 은 전역 적 이 고 추상 적 인 특징 정 보 를 포함한다.다시 말 하면 볼 륨 망 의 서로 다른 층 의 활성화 치 는 서로 다른 공간 척도 에서 이미지 내용 의 분 해 를 제공 한 다 는 것 이다.따라서 convnet 의 상부 표 시 를 통 해 더욱 전면적 이 고 추상 적 인 이미지 내용 을 포착 하 기 를 기대한다.콘 텐 츠 손실 함수 의 또 다른 선택 은 대상 이미지 에서 계 산 된 프 리 트 레이 닝 네트워크 의 상부 활성화 와 생 성 된 이미지 에서 계 산 된 동일 층 활성화 사이 의 L2 범 수 입 니 다.이것 은 상부 에서 본 생 성 된 이미지 가 원시 목표 이미지 와 유사 해 보일 수 있 도록 보장 한다.볼 륨 망 의 상층 부 에서 그림 을 입력 하 는 내용 을 본다 고 가정 하면 이것 이 바로 이미지 내용 을 저장 하 는 방식 이다.
스타일 손실 함수
콘 텐 츠 손실 함 수 는 하나의 상층 부 만 사용 하지만 Gatys 가 정의 하 는 스타일 손실 함 수 는 여러 개의 convnet 층 을 사용 합 니 다. convnet 에서 추출 한 모든 공간 비율의 스타일 참조 이미지 의 외관 을 캡 처 하려 고 합 니 다. 단일 비율 만 이 아 닙 니 다.스타일 의 손실 에 대해 Gatys 는 그래 픽 을 사용 하여 활성 화 된 Gram 매트릭스: 주어진 그래 픽 의 요소 그림 의 내 적 을 사용 합 니 다.이 내 적 은 층 의 특징 간 의 상관 성 을 나타 내 는 그림 으로 이해 할 수 있다.이러한 특징 은 관련 성 이 특정 공간 척도 모델 의 통계 데 이 터 를 포착 하고 경험 적 으로 이 척도 에서 찾 은 무늬 의 외관 에 대응한다.따라서 스타일 손실 은 스타일 참조 이미지 와 생 성 된 이미지 사이 에 서로 다른 층 의 활성화 내 유사 한 내부 상관 성 을 유지 하 는 데 목적 을 둔다.반대로 이것 은 서로 다른 공간의 척도 에서 찾 은 무늬 가 스타일 참조 이미지 와 생 성 된 이미지 에서 비슷 해 보 이 는 것 을 보장 한다.
미리 훈련 된 네트워크 모델 을 사용 하여 손실 함 수 를 정의 할 수 있 습 니 다.
Keras 실현
VGG 19 네트워크 모델 을 사용 하여 스타일 이전 을 실현 합 니 다.흐름:
스타일 그림, 대상 그림 경로 주 소 를 정의 합 니 다.두 장의 처리 그림 의 크기 가 같 도록 (크기 가 다 르 면 처리 난이도 가 증가 합 니 다) 두 장의 그림 을 resize 작업 을 하고 크기 는 400 px 입 니 다.초기 변수 정의
from keras.preprocessing.image import load_img,img_to_array
target_image_path = 'img/protrait.jpg'
style_reference_image_path = 'img/transfer_style_reference.jpg'
width, height = load_img(target_image_path).size
img_height = 400
img_width = int(width*img_height/height)
보조 함 수 를 정의 하여 불 러 오기 편리, 예 처리, 후기 처리 VGG 19 볼 륨 네트워크 수신 과 생 성 된 그림 을 정의 합 니 다.보조 함수
import numpy as np
from keras.applications import vgg19
def preprocess_image(image_path):
img = load_img(image_path,target_size=(img_height,img_width))
img = img_to_array(img)
img = np.expand_dims(img,axis=0)
img = vgg19.preprocess_input(img)
return img
def deprocess_image(x):
x[:,:,0] += 103.939#zero-centering 0 :
x[:,:,1] += 116.779
x[:,:,2] += 123.68
x = x[:,:,::-1]#BGR---> RGB
x = np.clip(x,0,255).astype('uint8')
return x
vgg 19 네트워크 설정.스타일 이미지, 대상 이미지, 그림 을 만 드 는 placeholder 세 장의 그림 을 batch 로 입력 합 니 다.
예비 훈련 VGG 19 모델 로드, 응용
from keras import backend as K
target_image = K.constant(preprocess_image(target_image_path))
style_reference_image=K.constant(preprocess_image(style_reference_image_path))
combination_image = K.placeholder((1,img_height,img_width,3))#
input_tensor = K.concatenate([target_image,style_reference_image,
combination_image],axis=0)#
model = vgg19.VGG19(input_tensor=input_tensor,weights='imagenet',include_top=False)
print("Model loaded.")
콘 텐 츠 손실 을 정의 하여 대상 이미지 와 생 성 이미지 가 VGG 19 볼 륨 네트워크 의 상부 네트워크 에서 비슷 하도록 합 니 다.내용 손실
def content_loss(base,combination):
return K.sum(K.square(combination-base))
스타일 손실 정의.보조 함 수 를 사용 하여 Gram 행렬 을 계산 합 니 다: 원시 특징 행렬 에서 찾 은 관련 그림 입 니 다.스타일 손실
def gram_matrix(x):
features = K.batch_flatten(K.permute_dimensions(x,(2,0,1)))
gram = K.dot(features,K.transpose(features))
return gram
def style_loss(style,combination):
S = gram_matrix(style)
C = gram_matrix(combination)
channels = 3
size = img_height*img_width
return K.sum(K.square(S-C)) / (4.*(channels ** 2) * (size ** 2))
이 두 가지 손실 함 수 를 제외 하고 세 번 째: 총 변이 손실 을 추가 하여 생 성 된 조합 이미지 의 픽 셀 을 조작 합 니 다.이 는 생 성 된 이미지 의 공간 연속 성 을 장려 하여 과도 한 픽 셀 화 결 과 를 피한다.이 를 정규 화 손실 로 해석 할 수 있다.변이 손실
def total_variation_loss(x):
a = K.square(
x[:,:img_height-1,:img_width-1,:]-
x[:,1:,:img_width-1,:]
)
b = K.square(
x[:,img_height-1,:img_width-1,:] -
x[:,:img_height-1,1:,:]
)
return K.sum(K.pow(a+b, 1.25))
손실 함 수 를 최소 화 하 는 것 은 세 가지 손실 함수 의 가중 평균 이다.내용 손실 을 계산 하기 위해 서 는 상부 네트워크 인 block 5 만 사용 해 야 합 니 다.conv 2 네트워크 층;스타일 손실 을 계산 하려 면 여러 개의 네트워크 층 을 사용 해 야 한다. 바 텀 네트워크 에서 고 층 네트워크 까지.마지막 으로 변이 손실 까지.
스타일 이미지 와 콘 텐 츠 이미지 사용 에 의존 하여 콘 텐 츠 를 약간 조정 해 야 할 수도 있 습 니 다weight 계수.대 콘 텐 츠weight 는 목표 내용 이 생 성 된 그림 에서 쉽게 식별 된다 는 것 을 의미한다.최종 손실 함수 정의
output_dict = dict([(layer.name,layer.output) for layer in model.layers])
content_layer = 'block5_conv2'
style_layers = ['block1_conv1','block2_conv1',
'block3_conv1','block4_conv1','block5_conv1']
total_variation_weight = 1e-4
style_weight = 1.
content_weight = 0.025
loss = K.variable(0.)#
layer_features = outputs_dict[content_layer]
target_image_features = layer_features[0, :, :, :]
combination_features = layer_features[2, :, :, :]
loss+=content_weight*content_loss(target_image_features,combination_features)#
for layer_name in style_layers:#
layer_features = outputs_dict[layer_name]
style_reference_features = layer_features[1, :, :, :]
combination_features = layer_features[2, :, :, :]
sl = style_loss(style_reference_features, combination_features)
loss += (style_weight / len(style_layers)) * sl
# ,
loss += total_variation_weight * total_variation_loss(combination_image)
마지막 으로 경사도 하강 알고리즘 을 사용한다.Gatys 논문 에 서 는 L - BFGS 알고리즘 을 사용 했다.L - BFGS 알고리즘 은 Scipy 패키지 에 포함 되 어 있 으 며 Scipy 구현 에 두 가지 제한 이 있 습 니 다.
손실 함수 의 값 과 경사도 의 값 을 단독으로 계산 하 는 것 은 비효 율 적 이다. 이렇게 하면 이들 사이 의 대량의 잉여 계산 을 초래 할 수 있 기 때문이다.이 과정 은 거의 공동 계산 과정의 두 배 이다.이 를 돌아 가 려 면 Evaluator 라 는 Python 류 를 설정 하고 손실 값 과 경사도 값 을 계산 하 며 첫 번 째 호출 시 손실 값 을 되 돌려 주 고 다음 호출 경사도 를 캐 시 합 니 다.경사도 업데이트
grads = K.gradients(loss, combination_image)[0]
fetch_loss_and_grads = K.function([combination_image], [loss, grads])
class Evaluator(object):
def __init__(self):
self.loss_value = None
self.grads_values = None
def loss(self, x):
assert self.loss_value is None
x = x.reshape((1, img_height, img_width, 3))
outs = fetch_loss_and_grads([x])
loss_value = outs[0]
grad_values = outs[1].flatten().astype('float64')
self.loss_value = loss_value
self.grad_values = grad_values
return self.loss_value
def grads(self, x):
assert self.loss_value is not None
grad_values = np.copy(self.grad_values)
self.loss_value = None
self.grad_values = None
return grad_values
evaluator = Evaluator()
최종 적 으로 Scipy 의 L - BFGS 알고리즘 을 사용 하여 현재 생 성 된 그림 을 교체 할 때마다 경사도 가 낮 아 집 니 다.스타일 이동 순환
from scipy.optimize import fmin_l_bfgs_b
from scipy.misc import imsave
import time
result_prefix = 'my_result'
iterations = 20
x = preprocess_image(target_image_path)#
x = x.flatten()# , l-bfgs
for i in range(iterations):
print('Start of iteration', i)
start_time = time.time()
# L-BFGS ;
x, min_val, info = fmin_l_bfgs_b(evaluator.loss, x,
fprime=evaluator.grads,maxfun=20)
print('Current loss value:', min_val)
img = x.copy().reshape((img_height, img_width, 3))
img = deprocess_image(img)
fname = result_prefix + '_at_iteration_%d.png' % i
imsave(fname, img)
print('Image saved as', fname)
end_time = time.time()
print('Iteration %d completed in %ds' % (i, end_time - start_time))
이런 기술 이 실현 하 는 것 은 이미지 재 구성 이나 무늬 전이 의 한 형식 일 뿐 이라는 것 을 기억 하 세 요.이 는 강력 한 무늬 와 고도 의 유사 성 을 가 진 스타일 참조 이미지 에 가장 적합 하 며, 내용 목 표 는 식별 할 수 있 도록 높 은 수준의 디 테 일 을 필요 로 하지 않 는 다.그것 은 보통 초상 의 풍격 을 다른 초상 으로 옮 기 는 등 상당히 추상 적 인 기능 을 실현 할 수 없다.이 알고리즘 은 AI 가 아 닌 고전 신호 처리 에 더 가깝다.
또한 이 스타일 의 이전 알고리즘 을 실행 하 는 것 이 느 리 니 주의 하 세 요.그러나 설정 작업 의 전환 은 매우 간단 하 다. 적당 한 훈련 데이터 만 있 으 면 소형, 빠 른 피 드 볼 륨 네트워크 를 통 해 학습 할 수 있다.따라서 먼저 대량의 계산 주 기 를 들 여 고정 스타일 참조 이미지 의 입 출력 훈련 예 시 를 생 성하 고 개술 적 인 방법 을 사용 한 다음 에 간단 한 convnet 를 훈련 시 켜 이런 특정한 스타일 전환 을 학습 하여 빠 른 스타일 전환 을 실현 할 수 있다.일단 완성 되면 주어진 그림 을 스타일 화 하 는 것 은 즉각 적 인 것 이다. 이것 은 단지 이 작은 전방 향 전달 일 뿐이다.
작은 매듭
다음으로 전송:https://www.cnblogs.com/ysugyl/p/9574474.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.