【물체 검출】YOLOv4를 iOS상에서 움직인다
소개
마지막으로, 물체 탐지의 모델인 YOLO의 최신 버전 v4가 발표되었습니다!
속도를 유지한 채 크게 정밀도를 올릴 수 있었던 것 같습니다!
그런 YOLOv4를 이번에는 iOS에서 움직여 보았습니다.
환경
python=3.7.2
tensorflow=1.13.1
keras=2.3.1
coremltools=3.3
YOLOv4에 대한 학습된 모델 얻기
여기에서 다운로드할 수 있습니다.
학습된 모델 변환 Darknet → (Keras →) CoreML
Darknet에서 학습한 or 학습한 모델을 iOS에서 움직일 수 있도록 변환합니다.
내부에서는 일단 Keras의 모델로 변환되고 나서 CoreML용의 모델로 변환되고 있습니다.
컨버터는 YOLOv3의 것을 기반으로합니다. ( keras-yolo3/convert.py )
따라서 YOLOv4에서 채택한 Mish Activation 레이어에 새롭게 대응시켜야 합니다.
우선 레이어 정의에서
convert.pyclass Mish(Layer):
def __init__(self, **kwargs):
super(Mish, self).__init__(**kwargs)
self.supports_masking = True
def call(self, inputs):
return inputs * K.tanh(K.softplus(inputs))
def get_config(self):
config = super(Mish, self).get_config()
return config
def compute_output_shape(self, input_shape):
return input_shape
이 레이어를 activation == 'Mish'
의 경우에 적응해 줍니다.
convert.pyif activation == 'linear':
all_layers.append(prev_layer)
elif activation == 'mish':
act_layer = Mish()(prev_layer)
prev_layer = act_layer
all_layers.append(act_layer)
elif activation == 'leaky':
act_layer = LeakyReLU(alpha=0.1)(prev_layer)
prev_layer = act_layer
all_layers.append(act_layer)
또한 CoreML 측에도 Mish 레이어에 대한 정보를 제공해야 합니다.
제대로 className
를 주지 않으면 Xcode 측에서 올바르게 읽을 수없는 것 같습니다.
convert.pydef convert_mish(layer):
params = NeuralNetwork_pb2.CustomLayerParams()
params.className = "Mish"
params.description = "Mish Activation Layer"
return params
convert.pycoreml_model = coremltools.converters.keras.convert(
model, input_names='input1', image_input_names='input1',
output_names=['output3', 'output2', 'output1'], image_scale=1/255.,
add_custom_layers=True,custom_conversion_functions={ "Mish": convert_mish })
convert.py 소스 코드
zshpython3 convert.py yolov4.cfg yolov4.weights yolov4.mlmodel
실행하면 다음과 유사한 오류가 발생하지만 문제가 없습니다. yolov4.mlmodel
가 작성되었다고 생각합니다.
You will not be able to run predict() on this Core ML model. Underlying exception message was: Error compiling model: "compiler error: Error creating Core ML custom layer implementation from factory for layer "Mish".".
RuntimeWarning)
iOS에서 실행
이번에 사용한 기기는 iPhone XS, iOS 13.3입니다.
작성한 .mlmodel
를 사용하기 위해 이번 리포지토리를 사용했습니다.
.mlmodel
를 프로젝트 폴더에 넣습니다.
모델을 이번에 만든 모델로 전환합니다.
YOLO.swift// let model = YOLOv3()
let model = Yolov4()
Mish 레이어 만들기
Swift 측에도 Mish 레이어를 정의합니다.
Mish.swift@objc(Mish) class Mish: NSObject, MLCustomLayer {
// (略)
func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray]) throws {
for i in 0..<inputs.count {
let input = inputs[i]
let output = outputs[i]
let count = input.count
let iptr = UnsafeMutablePointer<Float>(OpaquePointer(input.dataPointer))
let optr = UnsafeMutablePointer<Float>(OpaquePointer(output.dataPointer))
var countAsInt32 = Int32(count)
var one: Float = 1
let vdspLength = vDSP_Length(count)
vvexpf(optr, iptr, &countAsInt32)
vDSP_vsadd(optr, 1, &one, optr, 1,vdspLength)
vvlogf(optr, optr, &countAsInt32)
vvtanhf(optr, optr, &countAsInt32)
vDSP_vmul(optr, 1, iptr, 1, optr, 1, vdspLength)
}
}
}
후반에 vvexpf
라든지, vDSP_vsadd
라든지의 키모인 함수가 줄지어 있습니다만, 수치 계산 등을 고속으로 처리해 주는 함수 같고,
Accelerate라고 말하는 것 같습니다. Apple Document | Accelerate
여기의 부분, 보기 쉽게 쓰면 다음과 같은 느낌이 됩니다만, YOLOv4 중에서 72회 불리고 있다고 하는 일도 있어, for문으로 1개 1개 처리하고 있으면 굉장히 무거워져 버리는군요, 그래서 배열로 단번에 계산하자는 느낌입니다.
for j in 0..<input.count {
let x = input[j].floatValue
let y = x / (1 + exp(-x))
output[j] = NSNumber(value: y)
}
그 밖에도 GPU를 사용하도록 하고 있습니다.Mish.metal
는 Mish.swift
와 같은 장소에 둡니다.
Mish.swift
Mish.metal
실행의 모습
무사히 실행할 수 있었지만 전반적으로 모사리입니다. 그리고, 정밀도도 YOLOv3 와 비교해 오히려 나빠지고 있는 것 같은 인상을 받습니다.
YOLOv4
YOLOv3
조사해 보면, Mish 레이어를 무효로 하고 있는 경우의 CPU 사용률은 160% 정도(아마 최대 400%), 메모리 사용량은 60MB 정도인 것에 대해, 유효하게 하고 있는 경우의 CPU 사용률은 30% 정도, 사용 메모리는 250MB까지 증가합니다.
메모리를 굉장히 사용하는데 있어서, CPU를 그다지 사용할 수 없다고 하는 형태군요. 이 근처는 Swift 측의 코드를 최적화하는 것이 맞을 것 같습니다.
Reference
이 문제에 관하여(【물체 검출】YOLOv4를 iOS상에서 움직인다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/TakaoNarikawa/items/e4521fd8c7a522e9d4fd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
python=3.7.2
tensorflow=1.13.1
keras=2.3.1
coremltools=3.3
YOLOv4에 대한 학습된 모델 얻기
여기에서 다운로드할 수 있습니다.
학습된 모델 변환 Darknet → (Keras →) CoreML
Darknet에서 학습한 or 학습한 모델을 iOS에서 움직일 수 있도록 변환합니다.
내부에서는 일단 Keras의 모델로 변환되고 나서 CoreML용의 모델로 변환되고 있습니다.
컨버터는 YOLOv3의 것을 기반으로합니다. ( keras-yolo3/convert.py )
따라서 YOLOv4에서 채택한 Mish Activation 레이어에 새롭게 대응시켜야 합니다.
우선 레이어 정의에서
convert.pyclass Mish(Layer):
def __init__(self, **kwargs):
super(Mish, self).__init__(**kwargs)
self.supports_masking = True
def call(self, inputs):
return inputs * K.tanh(K.softplus(inputs))
def get_config(self):
config = super(Mish, self).get_config()
return config
def compute_output_shape(self, input_shape):
return input_shape
이 레이어를 activation == 'Mish'
의 경우에 적응해 줍니다.
convert.pyif activation == 'linear':
all_layers.append(prev_layer)
elif activation == 'mish':
act_layer = Mish()(prev_layer)
prev_layer = act_layer
all_layers.append(act_layer)
elif activation == 'leaky':
act_layer = LeakyReLU(alpha=0.1)(prev_layer)
prev_layer = act_layer
all_layers.append(act_layer)
또한 CoreML 측에도 Mish 레이어에 대한 정보를 제공해야 합니다.
제대로 className
를 주지 않으면 Xcode 측에서 올바르게 읽을 수없는 것 같습니다.
convert.pydef convert_mish(layer):
params = NeuralNetwork_pb2.CustomLayerParams()
params.className = "Mish"
params.description = "Mish Activation Layer"
return params
convert.pycoreml_model = coremltools.converters.keras.convert(
model, input_names='input1', image_input_names='input1',
output_names=['output3', 'output2', 'output1'], image_scale=1/255.,
add_custom_layers=True,custom_conversion_functions={ "Mish": convert_mish })
convert.py 소스 코드
zshpython3 convert.py yolov4.cfg yolov4.weights yolov4.mlmodel
실행하면 다음과 유사한 오류가 발생하지만 문제가 없습니다. yolov4.mlmodel
가 작성되었다고 생각합니다.
You will not be able to run predict() on this Core ML model. Underlying exception message was: Error compiling model: "compiler error: Error creating Core ML custom layer implementation from factory for layer "Mish".".
RuntimeWarning)
iOS에서 실행
이번에 사용한 기기는 iPhone XS, iOS 13.3입니다.
작성한 .mlmodel
를 사용하기 위해 이번 리포지토리를 사용했습니다.
.mlmodel
를 프로젝트 폴더에 넣습니다.
모델을 이번에 만든 모델로 전환합니다.
YOLO.swift// let model = YOLOv3()
let model = Yolov4()
Mish 레이어 만들기
Swift 측에도 Mish 레이어를 정의합니다.
Mish.swift@objc(Mish) class Mish: NSObject, MLCustomLayer {
// (略)
func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray]) throws {
for i in 0..<inputs.count {
let input = inputs[i]
let output = outputs[i]
let count = input.count
let iptr = UnsafeMutablePointer<Float>(OpaquePointer(input.dataPointer))
let optr = UnsafeMutablePointer<Float>(OpaquePointer(output.dataPointer))
var countAsInt32 = Int32(count)
var one: Float = 1
let vdspLength = vDSP_Length(count)
vvexpf(optr, iptr, &countAsInt32)
vDSP_vsadd(optr, 1, &one, optr, 1,vdspLength)
vvlogf(optr, optr, &countAsInt32)
vvtanhf(optr, optr, &countAsInt32)
vDSP_vmul(optr, 1, iptr, 1, optr, 1, vdspLength)
}
}
}
후반에 vvexpf
라든지, vDSP_vsadd
라든지의 키모인 함수가 줄지어 있습니다만, 수치 계산 등을 고속으로 처리해 주는 함수 같고,
Accelerate라고 말하는 것 같습니다. Apple Document | Accelerate
여기의 부분, 보기 쉽게 쓰면 다음과 같은 느낌이 됩니다만, YOLOv4 중에서 72회 불리고 있다고 하는 일도 있어, for문으로 1개 1개 처리하고 있으면 굉장히 무거워져 버리는군요, 그래서 배열로 단번에 계산하자는 느낌입니다.
for j in 0..<input.count {
let x = input[j].floatValue
let y = x / (1 + exp(-x))
output[j] = NSNumber(value: y)
}
그 밖에도 GPU를 사용하도록 하고 있습니다.Mish.metal
는 Mish.swift
와 같은 장소에 둡니다.
Mish.swift
Mish.metal
실행의 모습
무사히 실행할 수 있었지만 전반적으로 모사리입니다. 그리고, 정밀도도 YOLOv3 와 비교해 오히려 나빠지고 있는 것 같은 인상을 받습니다.
YOLOv4
YOLOv3
조사해 보면, Mish 레이어를 무효로 하고 있는 경우의 CPU 사용률은 160% 정도(아마 최대 400%), 메모리 사용량은 60MB 정도인 것에 대해, 유효하게 하고 있는 경우의 CPU 사용률은 30% 정도, 사용 메모리는 250MB까지 증가합니다.
메모리를 굉장히 사용하는데 있어서, CPU를 그다지 사용할 수 없다고 하는 형태군요. 이 근처는 Swift 측의 코드를 최적화하는 것이 맞을 것 같습니다.
Reference
이 문제에 관하여(【물체 검출】YOLOv4를 iOS상에서 움직인다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/TakaoNarikawa/items/e4521fd8c7a522e9d4fd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Darknet에서 학습한 or 학습한 모델을 iOS에서 움직일 수 있도록 변환합니다.
내부에서는 일단 Keras의 모델로 변환되고 나서 CoreML용의 모델로 변환되고 있습니다.
컨버터는 YOLOv3의 것을 기반으로합니다. ( keras-yolo3/convert.py )
따라서 YOLOv4에서 채택한 Mish Activation 레이어에 새롭게 대응시켜야 합니다.
우선 레이어 정의에서
convert.py
class Mish(Layer):
def __init__(self, **kwargs):
super(Mish, self).__init__(**kwargs)
self.supports_masking = True
def call(self, inputs):
return inputs * K.tanh(K.softplus(inputs))
def get_config(self):
config = super(Mish, self).get_config()
return config
def compute_output_shape(self, input_shape):
return input_shape
이 레이어를
activation == 'Mish'
의 경우에 적응해 줍니다.convert.py
if activation == 'linear':
all_layers.append(prev_layer)
elif activation == 'mish':
act_layer = Mish()(prev_layer)
prev_layer = act_layer
all_layers.append(act_layer)
elif activation == 'leaky':
act_layer = LeakyReLU(alpha=0.1)(prev_layer)
prev_layer = act_layer
all_layers.append(act_layer)
또한 CoreML 측에도 Mish 레이어에 대한 정보를 제공해야 합니다.
제대로
className
를 주지 않으면 Xcode 측에서 올바르게 읽을 수없는 것 같습니다.convert.py
def convert_mish(layer):
params = NeuralNetwork_pb2.CustomLayerParams()
params.className = "Mish"
params.description = "Mish Activation Layer"
return params
convert.py
coreml_model = coremltools.converters.keras.convert(
model, input_names='input1', image_input_names='input1',
output_names=['output3', 'output2', 'output1'], image_scale=1/255.,
add_custom_layers=True,custom_conversion_functions={ "Mish": convert_mish })
convert.py 소스 코드
zsh
python3 convert.py yolov4.cfg yolov4.weights yolov4.mlmodel
실행하면 다음과 유사한 오류가 발생하지만 문제가 없습니다.
yolov4.mlmodel
가 작성되었다고 생각합니다.You will not be able to run predict() on this Core ML model. Underlying exception message was: Error compiling model: "compiler error: Error creating Core ML custom layer implementation from factory for layer "Mish".".
RuntimeWarning)
iOS에서 실행
이번에 사용한 기기는 iPhone XS, iOS 13.3입니다.
작성한 .mlmodel
를 사용하기 위해 이번 리포지토리를 사용했습니다.
.mlmodel
를 프로젝트 폴더에 넣습니다.
모델을 이번에 만든 모델로 전환합니다.
YOLO.swift// let model = YOLOv3()
let model = Yolov4()
Mish 레이어 만들기
Swift 측에도 Mish 레이어를 정의합니다.
Mish.swift@objc(Mish) class Mish: NSObject, MLCustomLayer {
// (略)
func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray]) throws {
for i in 0..<inputs.count {
let input = inputs[i]
let output = outputs[i]
let count = input.count
let iptr = UnsafeMutablePointer<Float>(OpaquePointer(input.dataPointer))
let optr = UnsafeMutablePointer<Float>(OpaquePointer(output.dataPointer))
var countAsInt32 = Int32(count)
var one: Float = 1
let vdspLength = vDSP_Length(count)
vvexpf(optr, iptr, &countAsInt32)
vDSP_vsadd(optr, 1, &one, optr, 1,vdspLength)
vvlogf(optr, optr, &countAsInt32)
vvtanhf(optr, optr, &countAsInt32)
vDSP_vmul(optr, 1, iptr, 1, optr, 1, vdspLength)
}
}
}
후반에 vvexpf
라든지, vDSP_vsadd
라든지의 키모인 함수가 줄지어 있습니다만, 수치 계산 등을 고속으로 처리해 주는 함수 같고,
Accelerate라고 말하는 것 같습니다. Apple Document | Accelerate
여기의 부분, 보기 쉽게 쓰면 다음과 같은 느낌이 됩니다만, YOLOv4 중에서 72회 불리고 있다고 하는 일도 있어, for문으로 1개 1개 처리하고 있으면 굉장히 무거워져 버리는군요, 그래서 배열로 단번에 계산하자는 느낌입니다.
for j in 0..<input.count {
let x = input[j].floatValue
let y = x / (1 + exp(-x))
output[j] = NSNumber(value: y)
}
그 밖에도 GPU를 사용하도록 하고 있습니다.Mish.metal
는 Mish.swift
와 같은 장소에 둡니다.
Mish.swift
Mish.metal
실행의 모습
무사히 실행할 수 있었지만 전반적으로 모사리입니다. 그리고, 정밀도도 YOLOv3 와 비교해 오히려 나빠지고 있는 것 같은 인상을 받습니다.
YOLOv4
YOLOv3
조사해 보면, Mish 레이어를 무효로 하고 있는 경우의 CPU 사용률은 160% 정도(아마 최대 400%), 메모리 사용량은 60MB 정도인 것에 대해, 유효하게 하고 있는 경우의 CPU 사용률은 30% 정도, 사용 메모리는 250MB까지 증가합니다.
메모리를 굉장히 사용하는데 있어서, CPU를 그다지 사용할 수 없다고 하는 형태군요. 이 근처는 Swift 측의 코드를 최적화하는 것이 맞을 것 같습니다.
Reference
이 문제에 관하여(【물체 검출】YOLOv4를 iOS상에서 움직인다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/TakaoNarikawa/items/e4521fd8c7a522e9d4fd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
// let model = YOLOv3()
let model = Yolov4()
@objc(Mish) class Mish: NSObject, MLCustomLayer {
// (略)
func evaluate(inputs: [MLMultiArray], outputs: [MLMultiArray]) throws {
for i in 0..<inputs.count {
let input = inputs[i]
let output = outputs[i]
let count = input.count
let iptr = UnsafeMutablePointer<Float>(OpaquePointer(input.dataPointer))
let optr = UnsafeMutablePointer<Float>(OpaquePointer(output.dataPointer))
var countAsInt32 = Int32(count)
var one: Float = 1
let vdspLength = vDSP_Length(count)
vvexpf(optr, iptr, &countAsInt32)
vDSP_vsadd(optr, 1, &one, optr, 1,vdspLength)
vvlogf(optr, optr, &countAsInt32)
vvtanhf(optr, optr, &countAsInt32)
vDSP_vmul(optr, 1, iptr, 1, optr, 1, vdspLength)
}
}
}
for j in 0..<input.count {
let x = input[j].floatValue
let y = x / (1 + exp(-x))
output[j] = NSNumber(value: y)
}
무사히 실행할 수 있었지만 전반적으로 모사리입니다. 그리고, 정밀도도 YOLOv3 와 비교해 오히려 나빠지고 있는 것 같은 인상을 받습니다.
YOLOv4
YOLOv3
조사해 보면, Mish 레이어를 무효로 하고 있는 경우의 CPU 사용률은 160% 정도(아마 최대 400%), 메모리 사용량은 60MB 정도인 것에 대해, 유효하게 하고 있는 경우의 CPU 사용률은 30% 정도, 사용 메모리는 250MB까지 증가합니다.
메모리를 굉장히 사용하는데 있어서, CPU를 그다지 사용할 수 없다고 하는 형태군요. 이 근처는 Swift 측의 코드를 최적화하는 것이 맞을 것 같습니다.
Reference
이 문제에 관하여(【물체 검출】YOLOv4를 iOS상에서 움직인다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/TakaoNarikawa/items/e4521fd8c7a522e9d4fd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)