TensorFlow 2가 TensorFlow 1보다 훨씬 느린 이유는 무엇입니까?
많은 사용자들이 파이토치로 전환한 이유로 꼽아왔지만, 가장 중요한 실용적인 품질, 즉 속도를 희생하고 열정적인 실행을 할 수 있는 정당성/설명을 아직 찾지 못했습니다.
다음은 코드 벤치마킹 성능인 TF1 대 TF2입니다. TF1은 47%에서 276% 더 빠르게 실행됩니다.
제 질문은: 그래프 또는 하드웨어 수준에서 그렇게 큰 속도 저하를 초래하는 것은 무엇입니까?
자세한 답을 찾고 있습니다. 이미 광범위한 개념에 익숙합니다.관련 깃
사양: CUDA 10.0.130, cuDNN 7.4.2, Python 3.7.4, Windows 10, GTX 1070
벤치마크 결과:
업데이트: 아래 코드에 따라 활성화 실행을 비활성화하는 것은 도움이 되지 않습니다.그러나 이러한 동작은 일관성이 없습니다. 그래프 모드로 실행하는 것이 도움이 될 때도 있고, Eager에 비해 느리게 실행되는 경우도 있습니다.
벤치마크 코드:
# use tensorflow.keras... to benchmark tf.keras; used GPU for all above benchmarks
from keras.layers import Input, Dense, LSTM, Bidirectional, Conv1D
from keras.layers import Flatten, Dropout
from keras.models import Model
from keras.optimizers import Adam
import keras.backend as K
import numpy as np
from time import time
batch_shape = (32, 400, 16)
X, y = make_data(batch_shape)
model_small = make_small_model(batch_shape)
model_small.train_on_batch(X, y) # skip first iteration which builds graph
timeit(model_small.train_on_batch, 200, X, y)
K.clear_session() # in my testing, kernel was restarted instead
model_medium = make_medium_model(batch_shape)
model_medium.train_on_batch(X, y) # skip first iteration which builds graph
timeit(model_medium.train_on_batch, 10, X, y)
사용된 기능:
def timeit(func, iterations, *args):
t0 = time()
for _ in range(iterations):
func(*args)
print("Time/iter: %.4f sec" % ((time() - t0) / iterations))
def make_small_model(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = Conv1D(128, 400, strides=4, padding='same')(ipt)
x = Flatten()(x)
x = Dropout(0.5)(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_medium_model(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = Bidirectional(LSTM(512, activation='relu', return_sequences=True))(ipt)
x = LSTM(512, activation='relu', return_sequences=True)(x)
x = Conv1D(128, 400, strides=4, padding='same')(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(128, activation='relu')(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_data(batch_shape):
return np.random.randn(*batch_shape), np.random.randint(0, 2, (batch_shape[0], 1))
업데이트 8/1730/2020: TF 2.3은 마침내 이를 달성했습니다. 모든 사례가 이전 버전보다 더 빠르며 특히 더 빠릅니다.
게다가, 제 이전 업데이트는 TF에 불공평했습니다. 제 GPU가 최근 과열되고 있습니다.반복 시간의 증가하는 줄기 그림을 보면 신뢰할 수 있는 증상입니다.마지막으로, Eager vs Graph에서 개발자의 노트를 참조하십시오.
이 답변에 대한 마지막 업데이트가 될 수 있습니다.모델의 속도에 대한 실제 통계는 장치에서 사용자만 찾을 수 있습니다.
업데이트 5/19/2020: TF 2.2, 동일한 테스트 사용: Eager 속도가 약간 개선되었습니다.대규모 Numpy 그림train_on_batch
아래의 경우, x축은 연속적인 적합 반복입니다. GPU가 최대 용량에 가깝지 않기 때문에 조정 중인지 의심스럽지만 시간이 지남에 따라 반복 속도가 느려집니다.
위의 그래프와 Eager는 TF1보다 각각 1.56배, 1.97배 느립니다.TensorFlow의 사용자 지정/저수준 기능에 대한 지원이 부족한 경우 Pytorch로 전환하는 것을 고려하고 있기 때문에 이 문제를 더 디버깅하겠습니다.하지만 개발자들의 피드백을 받기 위해 이슈를 오픈했습니다.
업데이트 2/18/2020: 저는 2.1과 2.1-야간 벤치를 지켰습니다. 결과는 엇갈립니다.하나의 구성(모델 및 데이터 크기)을 제외한 모든 구성은 TF2 및 TF1의 최고 구성과 같거나 훨씬 빠릅니다.속도가 느리고 속도가 현저하게 느린 것은 그래프 실행에서 Large-Large입니다(특히 1.6배에서 2.5배 느림)입니다.
게다가, 그래프와 내가 테스트한 큰 모델에 대한 Eager 사이에는 극단적인 재현성 차이가 있습니다. 이는 무작위성/계산-병렬성을 통해 설명할 수 없습니다.저는 현재 이러한 클레임에 대해 시간당 제약 조건에 대해 재현 가능한 코드를 제시할 수 없으므로, 대신 당신의 모델에 대해 이 코드를 테스트하는 것을 강력히 추천합니다.
이것들에 대해 아직 Git 이슈를 열지 않았지만, 저는 원본에 대해 언급했습니다 - 아직 응답이 없습니다.진행되는 대로 답변을 업데이트하겠습니다.
평결: 당신이 무엇을 하고 있는지 안다면 그렇지 않습니다.하지만 그렇게 하지 않으면 평균적으로 몇 번의 GPU 업그레이드와 여러 번의 GPU 업그레이드로 인해 많은 비용이 발생할 수 있습니다. 최악의 경우도 마찬가지입니다.
이 답변: 문제에 대한 대략적인 설명과 요구 사항에 맞는 교육 구성을 결정하는 방법에 대한 지침을 제공하는 것을 목표로 합니다.모든 벤치마킹 결과 + 사용된 코드를 포함한 자세한 설명은 다른 답변을 참조하십시오.
추가 정보를 얻으면 답변을 업데이트할 것입니다. - 이 질문을 북마크하거나 "별표"로 표시하여 참조할 수 있습니다.
이슈 요약: TensorFlow 개발자 Q. Scott Zhu에 의해 확인된 바와 같이, TF2는 그래프 수준을 포함하여 TF 소스의 전면적인 변경을 포함한 Keras와의 긴밀한 통합에 중점을 두고 개발되었습니다.이점: 처리, 배포, 디버그 및 배포 기능이 크게 확장되었습니다.그러나 이들 중 일부의 비용은 속도입니다.
그러나 문제는 상당히 더 복잡합니다.TF1 대 TF2 뿐만 아니라 열차 속도에 상당한 차이를 보이는 요인은 다음과 같습니다.
- TF2 대 TF1
- 열심 대.그래프 모드
keras
대 대tf.keras
numpy
대 대tf.data.Dataset
어쨌든든...train_on_batch()
대 대fit()
- GPU 대 CPU
model(x)
대 대model.predict(x)
어쨌든든...
불행히도, 위의 것들 중 거의 어느 것도 다른 것들과 독립적이지 않으며, 각각은 다른 것들에 비해 실행 시간을 적어도 두 배로 늘릴 수 있습니다.다행히도 몇 가지 바로 가기를 사용하여 체계적으로 가장 잘 작동할 항목을 결정할 수 있습니다.
어떻게 해야 합니까?현재 유일한 방법은 특정 모델, 데이터 및 하드웨어에 대한 실험입니다.단일 구성이 항상 가장 잘 작동하는 것은 아니지만 검색을 단순화하기 위해 해야 할 일과 하지 말아야 할 일이 있습니다.
>> 실행:
train_on_batch()
+numpy
+tf.keras
Eager/ + 절그기/래프간그프train_on_batch()
+numpy
+tf.keras
TF2 + 그래프fit()
+numpy
+tf.keras
+ + 모델 & TF1/TF2 + 그래프 + 대형모및터데
>> 금지:
fit()
+numpy
+keras
및 모델 및fit()
+numpy
+tf.keras
TF1/TF2 + 망열train_on_batch()
+numpy
+keras
TF1 + 열망전공]
tf.python.keras
10-100배 더 느리게 실행되고 많은 버그가 있을 수 있습니다. 자세한 정보- 여기에는 다음이 포함됩니다.
layers
,models
,optimizers
사용 및 " 가져오기는 하려면 & 관즉 " 시련기" , ops, utils utils "private" Alt 있를니확합다인여부사고용하확인는지만는및기오관련용▁are▁&다▁&니합가;확▁they'인▁imports▁in를여부out,ts▁imports▁"▁'▁fine"사private▁usage'▁for▁related▁check용고하▁ops"인tf.keras
- 여기에는 다음이 포함됩니다.
벤치마킹 설정 예는 다른 답변 하단의 코드를 참조하십시오.위의 목록은 주로 다른 답변의 "BENCHMARKS" 표를 기반으로 합니다.
위의 '해야 할 일과 하지 말아야 할 일'의 제한 사항:
- 이 질문의 제목은 "왜 TF2가 TF1보다 훨씬 느립니까?"이며, 본문은 교육과 관련되어 있지만 문제는 이에 국한되지 않습니다. 추론 역시 동일한 TF 버전, 가져오기, 데이터 형식 등 내에서도 상당한 속도 차이가 있을 수 있습니다. 이 답변을 참조하십시오.
- RNN은 TF2에서 개선되었기 때문에 다른 답변에서 데이터 그리드를 현저하게 변경할 가능성이 있습니다.
- 사용되는 은 로주사는모델입니다.
Conv1D
그리고.Dense
RNN, 희소 데이터/대상, 4/5D 입력 및 기타 구성 없음 - 입력 데이터가 다음으로 제한됨
numpy
그리고.tf.data.Dataset
하는 반면, 하세요. - GPU가 사용되었습니다. CPU에서 결과가 다릅니다.실제로 질문을 던졌을 때 CUDA가 제대로 구성되지 않았고 일부 결과는 CPU 기반이었습니다.
TF2가 열정적인 실행을 위해 가장 실용적인 품질, 속도를 희생한 이유는 무엇입니까?확실히, 그래프는 아직 사용할 수 있습니다.하지만 질문이 "왜 열정적인가"라면:
- 우수한 디버깅: "중간 계층 출력을 얻는 방법" 또는 "무게를 검사하는 방법"을 묻는 수많은 질문을 접하게 될 것입니다. 열정적으로, 그것은 다음과 같이 (거의) 간단합니다.
.__dict__
반대로 그래프는 특별한 백엔드 기능에 익숙해야 하므로 디버깅 및 검사의 전체 프로세스가 크게 복잡합니다. - 더 빠른 프로토타이핑: 위와 유사한 아이디어에 따라, 더 빠른 이해 = 실제 DL에 더 많은 시간이 남음.
활성화/비활성화 방법
tf.enable_eager_execution() # TF1; must be done before any model/tensor creation
tf.compat.v1.disable_eager_execution() # TF2; above holds
TF2에서 오해의 소지가 있습니다. 여기를 참조하십시오.
추가 정보:
- 를 하세요.
_on_batch()
TF2의 방법들; TF 개발에 따르면, 그들은 여전히 느린 구현을 사용하지만 의도적으로 사용하지는 않습니다. 즉, 수정되어야 합니다.자세한 내용은 다른 답변을 참조하십시오.
텐서플로 개발자에 대한 요청:
.train_on_batch()
그리고 전화의 성능 측면.fit()
반복적으로; 맞춤형 기차 루프는 많은 사람들, 특히 나에게 중요합니다.사용자가 알기 쉽게 이러한 성능 차이에 대한 문서/문서 문자열 언급을 추가합니다.일반 실행 속도를 향상시켜 피프가 파이토치로 이동하지 않도록 합니다.
승인:덕분에.
업데이트:
11/14/19 - Numpy 입력 데이터가 있는 모든* 구성에 대해 TF2에서 더 느리게 실행되는 모델(실제 애플리케이션에서)을 찾았습니다.차이는 13-19%, 평균 17%였습니다.사이의 차이점
keras
그리고.tf.keras
그러나 18-40%, 평균 32%(TF1 및 2 모두). (*- TF2 OOM이 포함된 Eager 제외)11/17/19 - 개발 업데이트됨
on_batch()
최근 커밋에서 속도가 향상되었다고 언급하는 방법 - TF 2.1에서 출시되거나 현재 사용 가능함tf-nightly
저는 후자를 실행할 수 없기 때문에 2.1까지 벤치마킹을 연기할 것입니다.2/20/20 - 예측 성능도 벤치마크할 가치가 있습니다. 예를 들어 TF2에서는 CPU 예측 시간이 주기적으로 급증할 수 있습니다.
이 답변: TF2 대 TF1 열차 루프, 입력 데이터 프로세서 및 Eager vs. 문제에 대한 자세한 그래프/하드웨어 수준의 설명을 제공하는 것을 목표로 합니다.그래프 모드 실행.문제 요약 및 해결 지침은 다른 답변을 참조하십시오.
성능 평가: 구성에 따라 하나가 더 빠를 수도 있고 다른 하나가 더 빠를 수도 있습니다.TF2 대 TF1의 경우 평균적으로 비슷하지만 상당한 구성 기반 차이가 존재하며 TF1이 TF2를 능가하는 경우가 많습니다.아래의 "벤치마크"를 참조하십시오.
간절한 VS. 그래프: 일부 사람들을 위한 이 전체 답변의 핵심:제가 테스트한 바로는 TF2의 열정은 TF1의 열정보다 느립니다.자세한 내용은 아래에 있습니다.
둘 사이의 근본적인 차이점은 Graph가 사전에 계산 네트워크를 설정하고 '지시'할 때 실행하는 반면 Eager는 생성 시 모든 것을 실행한다는 것입니다.하지만 이야기는 여기서 시작됩니다.
열망은 그래프가 없는 것이 아니며, 실제로 예상과 달리 대부분 그래프일 수 있습니다.주로 그래프가 실행됩니다. 여기에는 그래프의 상당 부분을 구성하는 모델 및 최적화 도구 가중치가 포함됩니다.
Eager는 실행 시 자체 그래프의 일부를 재구성합니다. 그래프가 완전히 작성되지 않은 직접적인 결과입니다. 프로파일러 결과를 참조하십시오.계산 오버헤드가 있습니다.
Eager는 Numpy 입력이 있으면 속도가 느려집니다. 이 Git 설명 및 코드에 따르면 Eager의 Numpy 입력에는 CPU에서 GPU로 텐서를 복사하는 오버헤드 비용이 포함됩니다.소스 코드를 살펴보면 데이터 처리 차이가 분명합니다. Eager는 Numpy를 직접 전달하는 반면 Graph는 텐서를 Numpy에게 전달합니다. 정확한 프로세스는 불확실하지만 나중에는 GPU 수준의 최적화가 수반되어야 합니다.
TF2 Eager가 TF1 Eager보다 느립니다. 이것은...뜻밖의아래의 벤치마킹 결과를 참조하십시오.차이는 무시할 수 있는 수준에서 유의한 수준까지 다양하지만 일관성이 있습니다.왜 그런지 확실하지 않습니다. TF가 설명하면 답변이 업데이트됩니다.
TF2 대 TF1: TFdev의 관련 부분을 인용합니다. Q. Scott Zhu의 답변 - 제가 강조하고 다시 쓴 부분:
즉, 런타임은 ops를 실행하고 파이썬 코드의 모든 줄에 대한 수치를 반환해야 합니다.단일 단계 실행의 특성으로 인해 실행 속도가 느려집니다.
는 TF2를 활용합니다.
tf.function
교육, 평가 및 예측을 위해 그래프를 작성합니다.모델에 대해 "실행 함수"라고 합니다.TF1에서 "실행 함수"는 FuncGraph로, TF 함수로서 일부 공통 구성 요소를 공유하지만 구현은 다릅니다.
프로세스 중에 train_on_batch(), test_on_batch() 및 predict_on_batch()에 대해 잘못된 구현을 남겼습니다.여전히 수치적으로 정확하지만 x_on_batch에 대한 실행 함수는 tf가 아닌 순수 python 함수입니다.함수 랩 파이썬 함수입니다.이로 인해 속도가 느려집니다.
TF2에서, 우리는 모든 입력 데이터를 다음과 같이 변환합니다.
tf.data.Dataset
단일 유형의 입력을 처리하기 위해 실행 기능을 통합할 수 있습니다.데이터셋 변환에 약간의 오버헤드가 있을 수 있으며, 이는 배치당 비용이 아닌 일회성 오버헤드라고 생각합니다.
위 마지막 단락의 마지막 문장과 아래 단락의 마지막 절과 함께:
모드에서의 저하를 함수를 하는@tf.eager @tf 있습 다니function이 파이썬 함수를 그래프로 변환하는 함수입니다.np 배열과 같은 숫자 값을 입력할 때, 본문은
tf.function
는 정적 그래프로 변환되어 최적화되고 최종 값을 반환합니다. 이 값은 빠르고 TF1 그래프 모드와 유사한 성능을 가져야 합니다.
저는 동의하지 않습니다. 제 프로파일링 결과에 따르면 Eager의 입력 데이터 처리가 Graph의 입력 데이터 처리보다 상당히 느립니다.또한, 에 대해 확신이 없습니다.tf.data.Dataset
특히, 그러나 Eager는 동일한 데이터 변환 방법을 여러 번 반복적으로 호출합니다(프로파일러 참조).
마지막으로, 개발자의 연결된 커밋:Keras v2 루프를 지원하기 위한 상당한 수의 변경 사항.
열차 루프: (1) 열망 대.그래프; (2) 입력 데이터 형식. 의 교육은 TF2에서 별도의 열차 루프로 진행됩니다._select_training_loop()
training.py , 다음 중 하나:
training_v2.Loop()
training_distributed.DistributionMultiWorkerTrainingLoop(
training_v2.Loop()) # multi-worker mode
# Case 1: distribution strategy
training_distributed.DistributionMultiWorkerTrainingLoop(
training_distributed.DistributionSingleWorkerTrainingLoop())
# Case 2: generator-like. Input is Python generator, or Sequence object,
# or a non-distributed Dataset or iterator in eager execution.
training_generator.GeneratorOrSequenceTrainingLoop()
training_generator.EagerDatasetOrIteratorTrainingLoop()
# Case 3: Symbolic tensors or Numpy array-like. This includes Datasets and iterators
# in graph mode (since they generate symbolic tensors).
training_generator.GeneratorLikeTrainingLoop() # Eager
training_arrays.ArrayLikeTrainingLoop() # Graph
각각 리소스 할당을 다르게 처리하고 성능과 기능에 영향을 미칩니다.
Train Loops: vs. vs. : 네 개의 각각은 가능한 모든 조합이 아닐 수도 있지만 서로 다른 Train Loops를 사용합니다. keras
'fit
를 들어,에서는 예를들어, 의형를사니다용의 합니다.fit_loop
를 들어, 예를 들어, 기호입니다.training_arrays.fit_loop()
그리고 그것들train_on_batch
사용할 수 있습니다K.function()
.tf.keras
에는 이전 섹션에서 부분적으로 설명한 보다 정교한 계층 구조가 있습니다.
Train Loops: 문서 - 다른 실행 방법 중 일부에 대한 관련 소스 문서 문자열:
다른 텐서플로 연산과 달리 파이썬 수치 입력을 텐서로 변환하지 않습니다.또한, 각각의 고유한 파이썬 수치에 대해 새로운 그래프가 생성됩니다.
function
고유한 모든 입력 모양 및 데이터 유형 집합에 대해 별도의 그래프를 인스턴스화합니다.
한
tf.function
개체는 후드 아래의 여러 계산 그래프에 매핑해야 할 수 있습니다.이는 성능으로만 표시되어야 합니다(추적 그래프의 계산 및 메모리 비용이 0이 아님).
입력 데이터 프로세서: 위와 유사하게 프로세서는 런타임 구성(실행 모드, 데이터 형식, 배포 전략)에 따라 설정된 내부 플래그에 따라 케이스 바이 케이스로 선택됩니다.가장 간단한 경우는 Numpy 어레이와 직접 작동하는 Eager입니다.몇 가지 구체적인 예는 다음 답변을 참조하십시오.
모델 크기, 데이터 크기:
- 결정적입니다. 단일 구성이 모든 모델 및 데이터 크기에서 상위를 차지하지 않습니다.
- 모델 크기와 관련된 데이터 크기가 중요합니다. 소규모 데이터 및 모델의 경우 데이터 전송(예: CPU에서 GPU) 오버헤드가 지배적일 수 있습니다.마찬가지로 소규모 오버헤드 프로세서는 데이터 변환 시간당 대용량 데이터에서 더 느리게 실행될 수 있습니다( 참조).
convert_to_tensor
"프로파일러"에서) - 속도는 열차 루프와 입력 데이터 프로세서의 자원 처리 방법에 따라 다릅니다.
벤치마크: 갈은 고기. -- 워드 문서 -- 엑셀 스프레드시트.
용어:
- %-작은 숫자는 모두 초입니다.
- 로계된으로 됩니다.
(1 - longer_time / shorter_time)*100
이론적 근거: 우리는 어떤 요소가 다른 요소보다 빠릅니까?shorter / longer
는 사실 관계로 할 때 . - 부호 결정:
- 대 TF2 » TF1:
+
TF2가 더 빠른 경우 - GvE(간절함):
+
가 더
- 대 TF2 » TF1:
- TF2 = TensorFlow 2.0.0 + Keras 2.3.1; TF1 = TensorFlow 1.14.0 + Keras 2.2.5
프로파일러:
PROFILER - 설명:스파이더 3.3.6 IDE 프로파일러.
일부 기능은 다른 기능의 중첩에서 반복됩니다. 따라서 "데이터 처리" 기능과 "훈련" 기능 간의 정확한 분리를 추적하기가 어렵기 때문에 마지막 결과에서 언급한 것처럼 일부 중복이 발생합니다.
계산된 w.r.t. 런타임에서 빌드 시간을 뺀 수치
1회 또는 2회 호출된 모든(고유한) 런타임을 합산하여 계산한 빌드 시간
반복 횟수와 동일한 횟수로 불리는 모든 (고유한) 실행 시간과 일부 둥지 실행 시간을 합산하여 계산한 열차 시간
함수는 원래 이름에 따라 프로파일링됩니다(불행하게도).
_func = func
을 프필을다와과(음)로 합니다.func
빌드 가 있습니다.
테스트 환경:
- 최소한의 백그라운드 작업을 실행하면서 맨 아래에서 코드 실행
- 이 게시물에서 제안한 바와 같이 GPU는 타이밍 반복 전에 몇 번의 반복을 통해 "준비"되었습니다.
- CUDA 10.0.130, cuDNN 7.6.0, TensorFlow 1.14.0, TensorFlow 2.0.0 소스에서 빌드, Anaconda
- Python 3.7.4, Spyder 3.3.6 IDE
- GTX 1070, Windows 10, 24GB DDR4 2.4MHz RAM, i7-7700HQ 2.8GHz CPU
방법론:
- 벤치마크 '작은', '중간', '큰' 모델 및 데이터 크기
- 입력 데이터 크기와 상관없이 각 모델 크기에 대한 모수 수 수정
- "더 큰" 모델에는 더 많은 매개 변수와 계층이 있습니다.
- 가 더 동일한 "큰" 데이는시가더스동길일다니합만큰지퀀터▁"▁has,▁"다▁a니동합일lar큰▁but▁data"길▁same만.
batch_size
그리고.num_channels
- 은 모만사용만 합니다.
Conv1D
,Dense
가능한'; 회피된 '차이', TF 버전별 RNN. 차이점 - 모델 및 최적화 도구 그래프 작성을 생략하기 위해 항상 벤치마킹 루프 외부에서 하나의 트레인 적합치를 실행
- data(예: 를예지않하음용사터이데희소예▁(않:()를 :
layers.Embedding()
대상 ) 또는 예대상소희예(대상▁(▁): (▁sparse:SparseCategoricalCrossEntropy()
한계: "완전한" 답변은 가능한 모든 열차 루프와 반복기를 설명할 수 있지만, 그것은 확실히 제 시간 능력, 존재하지 않는 급여 또는 일반적인 필요를 초과합니다.결과는 방법론만큼만 좋습니다. 열린 마음으로 해석하십시오.
코드:
import numpy as np
import tensorflow as tf
import random
from termcolor import cprint
from time import time
from tensorflow.keras.layers import Input, Dense, Conv1D
from tensorflow.keras.layers import Dropout, GlobalAveragePooling1D
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
import tensorflow.keras.backend as K
#from keras.layers import Input, Dense, Conv1D
#from keras.layers import Dropout, GlobalAveragePooling1D
#from keras.models import Model
#from keras.optimizers import Adam
#import keras.backend as K
#tf.compat.v1.disable_eager_execution()
#tf.enable_eager_execution()
def reset_seeds(reset_graph_with_backend=None, verbose=1):
if reset_graph_with_backend is not None:
K = reset_graph_with_backend
K.clear_session()
tf.compat.v1.reset_default_graph()
if verbose:
print("KERAS AND TENSORFLOW GRAPHS RESET")
np.random.seed(1)
random.seed(2)
if tf.__version__[0] == '2':
tf.random.set_seed(3)
else:
tf.set_random_seed(3)
if verbose:
print("RANDOM SEEDS RESET")
print("TF version: {}".format(tf.__version__))
reset_seeds()
def timeit(func, iterations, *args, _verbose=0, **kwargs):
t0 = time()
for _ in range(iterations):
func(*args, **kwargs)
print(end='.'*int(_verbose))
print("Time/iter: %.4f sec" % ((time() - t0) / iterations))
def make_model_small(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = Conv1D(128, 40, strides=4, padding='same')(ipt)
x = GlobalAveragePooling1D()(x)
x = Dropout(0.5)(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_model_medium(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = ipt
for filters in [64, 128, 256, 256, 128, 64]:
x = Conv1D(filters, 20, strides=1, padding='valid')(x)
x = GlobalAveragePooling1D()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(128, activation='relu')(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_model_large(batch_shape):
ipt = Input(batch_shape=batch_shape)
x = Conv1D(64, 400, strides=4, padding='valid')(ipt)
x = Conv1D(128, 200, strides=1, padding='valid')(x)
for _ in range(40):
x = Conv1D(256, 12, strides=1, padding='same')(x)
x = Conv1D(512, 20, strides=2, padding='valid')(x)
x = Conv1D(1028, 10, strides=2, padding='valid')(x)
x = Conv1D(256, 1, strides=1, padding='valid')(x)
x = GlobalAveragePooling1D()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(128, activation='relu')(x)
x = Dense(64, activation='relu')(x)
out = Dense(1, activation='sigmoid')(x)
model = Model(ipt, out)
model.compile(Adam(lr=1e-4), 'binary_crossentropy')
return model
def make_data(batch_shape):
return np.random.randn(*batch_shape), \
np.random.randint(0, 2, (batch_shape[0], 1))
def make_data_tf(batch_shape, n_batches, iters):
data = np.random.randn(n_batches, *batch_shape),
trgt = np.random.randint(0, 2, (n_batches, batch_shape[0], 1))
return tf.data.Dataset.from_tensor_slices((data, trgt))#.repeat(iters)
batch_shape_small = (32, 140, 30)
batch_shape_medium = (32, 1400, 30)
batch_shape_large = (32, 14000, 30)
batch_shapes = batch_shape_small, batch_shape_medium, batch_shape_large
make_model_fns = make_model_small, make_model_medium, make_model_large
iterations = [200, 100, 50]
shape_names = ["Small data", "Medium data", "Large data"]
model_names = ["Small model", "Medium model", "Large model"]
def test_all(fit=False, tf_dataset=False):
for model_fn, model_name, iters in zip(make_model_fns, model_names, iterations):
for batch_shape, shape_name in zip(batch_shapes, shape_names):
if (model_fn is make_model_large) and (batch_shape == batch_shape_small):
continue
reset_seeds(reset_graph_with_backend=K)
if tf_dataset:
data = make_data_tf(batch_shape, iters, iters)
else:
data = make_data(batch_shape)
model = model_fn(batch_shape)
if fit:
if tf_dataset:
model.train_on_batch(data.take(1))
t0 = time()
model.fit(data, steps_per_epoch=iters)
print("Time/iter: %.4f sec" % ((time() - t0) / iters))
else:
model.train_on_batch(*data)
timeit(model.fit, iters, *data, _verbose=1, verbose=0)
else:
model.train_on_batch(*data)
timeit(model.train_on_batch, iters, *data, _verbose=1)
cprint(">> {}, {} done <<\n".format(model_name, shape_name), 'blue')
del model
test_all(fit=True, tf_dataset=False)
언급URL : https://stackoverflow.com/questions/58441514/why-is-tensorflow-2-much-slower-than-tensorflow-1
'programing' 카테고리의 다른 글
MariaDB가 한 데이터베이스에 대해 종속 하위 쿼리에 대해 색인을 사용하지 않지만 동일한 서버에 있는 다른 데이터베이스에는 사용하지 않음 (0) | 2023.06.15 |
---|---|
하향식 및 상향식 프로그래밍 (0) | 2023.06.15 |
셀이 범위 내에 있는지 여부를 VBA 테스트 (0) | 2023.06.15 |
Oracle에서 날짜에서 시간을 빼서 해당 날짜에도 영향을 미치도록 하는 방법 (0) | 2023.06.15 |
vuex 작업에서 반환되는 약속 내부의 VueJS 메서드 테스트 (0) | 2023.06.15 |