BrainScript를 사용하여 모델 편집
(참고: 이전 버전의 CNTK 이 용도로 "MEL"(모델 편집 언어)을 사용했습니다. 예제를 변환하는 중입니다. MEL에 대한 설명서는 여기를 참조하세요.)
CNTK 팩트 후에 모델을 편집할 수 있습니다. 이 작업은 수정 사항이 적용된 기존 모델을 복제(일부)하는 동안 새 모델을 만들어 수행합니다. 이를 위해 CNTK 세 가지 기본 함수를 제공합니다.
BS.Network.Load()
기존 모델을 로드하려면BS.Network.CloneFunction()
재사용을 위해 기존 모델의 섹션을 추출하려면BS.Network.Edit()
노드별 수정이 적용된 모델을 복제하려면
편집 작업은 별도의 단계가 아닙니다. 오히려 수정된 모델에서 작동해야 하는 명령은 모델을 로드할 수 있는 modelPath
명령이 BrainScriptNetworkBuilder
아니라 모델을 내부에 로드하고 로드된 모델을 즉시 새 모델을 생성하는 섹션을 지정합니다.
예: 차별 사전 학습
차별적 사전 학습은 일련의 얕은 네트워크를 학습하여 심층 네트워크를 만드는 기술입니다. 숨겨진 1개 계층 네트워크로 시작하고 부분 수렴으로 학습한 다음 출력 계층을 제거하고 숨겨진 새 계층을 추가하고 새 출력 계층을 추가합니다. 원하는 수의 숨겨진 레이어에 도달할 때까지 반복합니다.
매우 간단한 시작 모델로 가정해 보겠습니다.
BrainScriptNetworkBuilder = [
N = 40; M = 9000; H = 512
W1 = Parameter (H, N); b1 = Parameter (H)
Wout = Parameter (M, H); bout = Parameter (M)
x = Input (N, tag=‘feature’) ; labels = Input (M, tag=‘labels’)
h1 = Sigmoid (W1 * x + b1)
z = Wout * h1 + bout
ce = CrossEntropyWithSoftmax (labels, z, tag=‘criterion’)
]
이 모델을 학습하고 "model.1.dnn" 아래에 저장해 보겠습니다. 다음으로 두 개의 숨겨진 계층이 있는 모델을 학습하려고 합니다. 여기서 첫 번째 숨겨진 계층은 위에서 학습된 값에서 초기화됩니다. 이렇게 하려면 다음과 같이 새 모델을 만들지만 이전 모델의 일부를 다시 사용하는 별도의 학습 작업을 만듭니다.
BrainScriptNetworkBuilder = {
# STEP 1: load 1-hidden-layer model
inModel = BS.Network.Load ("model.1.dnn")
# get its h1 variable --and also recover its dimension
h1 = inModel.h1
H = h1.dim
# also recover the number of output classes
M = inModel.z.dim
# STEP 2: create the rest of the extended network as usual
W2 = Parameter (H, H); b2 = Parameter (H)
Wout = Parameter (M, H); bout = Parameter (M)
h2 = Sigmoid (W2 * h1 + b2)
z = Wout * h2 + bout
ce = CrossEntropyWithSoftmax (labels, z, tag=‘criterion’)
}
첫째, 1단계는 네트워크를 BrainScript 변수에 로드하는 데 사용합니다 Load()
. 네트워크는 모든 최상위 노드(노드 이름에 포함되지 .
[
않은 모든 노드)가 레코드 구문을 통해 액세스할 수 있는 BrainScript 레코드처럼 작동합니다. 새 네트워크는 로드된 네트워크의 모든 노드를 참조할 수 있습니다. 이 예제에서 로드된 네트워크에는 첫 번째 숨겨진 계층의 출력인 노드 h1
와 출력 클래스(Softmax 함수에 대한 입력)의 비정규화되지 않은 로그 후방 확률인 노드 z
가 포함됩니다. 두 노드 모두 BrainScript에서 점 구문(예: inModel.h1
및 inModel.z
)을 통해 액세스할 수 있습니다.
상수는 모델에 저장되지 않으므로 N
모델에서 사용할 수 없습니다 M
. 그러나 로드된 모델에서 다시 구성할 수 있습니다. 이를 위해 계산 노드는 BrainScript 레코드처럼 동작하고 속성을 노출합니다 dim
.
다음으로, 2단계는 일반 BrainScript를 사용하여 새 네트워크의 나머지 부분을 구성합니다. 이 새 섹션에서는 다른 노드 h1
를 사용하는 것처럼 입력 모델의 노드를 입력으로만 사용합니다. 입력 네트워크에서 노드를 참조하면 이 노드가 새로 만든 네트워크의 일부에 의존하는 모든 노드가 자동으로 만들어집니다. 예를 들어 입력 노드 x
는 자동으로 새 네트워크의 일부가 됩니다.
또한 출력 계층이 새로 생성됩니다. 이렇게 하면 모델 매개 변수가 새로 만들어집니다. (이렇게 하지 않고 기존 매개 변수를 다시 사용하려면 이 inModel.Wout
특정 예제의 네트워크 디자인 관점에서는 의미가 없습니다.)
예: 미리 학습된 모델 사용
다음은 미리 학습된 모델(파일 "./featext.dnn"
)을 기능 추출기로 사용하는 예제입니다.
BrainScriptNetworkBuilder = {
# STEP 1: load existing model
featExtNetwork = BS.Network.Load ("./featext.dnn")
# STEP 2: extract a read-only section that is the feature extractor function
featExt = BS.Network.CloneFunction (
featExtNetwork.input, # input node that AE model read data from
featExtNetwork.feat, # output node in AE model that holds the desired features
parameters="constant") # says to freeze that part of the network
# STEP 3: define the part of your network that uses the feature extractor
# from the loaded model, which above we isolated into featExt().
# featExt() can be used like any old BrainScript function.
input = Input (...)
features = featExt (input) # this will instantiate a clone of the above network
# STEP 4: and add the remaining bits of the network in BrainScript, e.g.
h = Sigmoid (W_hid * features + b_hid) # whatever your hidden layer looks like
z = W_out * h + b_out
ce = CrossEntropyWithSoftmax (labels, z)
criterionNodes = (ce)
}
1단계는 네트워크를 BrainScript 변수에 로드하는 데 사용합니다 Load()
.
2단계에서는 연결된 하위 그래프인 로드된 네트워크에서 기능 추출 관련 섹션을 복제하는 featExtNetwork.input
데 featExtNetwork.feat
사용합니다CloneFunction()
. 지정했 parameters="constant"
으므로 의존하는 모든 매개 변수 featExtNetwork.feat
도 복제되고 읽기 전용으로 만들어집니다.
3단계와 4단계에서 새 네트워크가 정의됩니다. 이 작업은 다른 BrainScript 모델과 마찬가지로 수행되며, 이제 함수를 featExt()
사용할 수 있습니다.
및 노드 이름 .
[
에 대한 문제 ]
해당 문자를 _
포함 .
하거나 [
]
대체한 네트워크의 노드를 참조하려면 .
예를 들어 호출 result.z
network.result.z
된 노드가 포함된 경우 network
실패합니다. 대신 다음과 같이 말합니다network.result_z
.
예: 기존 네트워크의 노드 수정
기존 네트워크의 내부 부분을 수정하려면 실제로 네트워크를 복제하는 반면 수정은 복제 프로세스의 일부로 적용됩니다. 이 작업은 .에 의해 BS.Network.Edit()
수행됩니다. Edit()
는 네트워크의 모든 노드를 반복하며 호출자가 전달한 람다 함수에 각 노드를 하나씩 제공합니다. 그런 다음 이러한 람다 함수는 노드를 검사하고 수정되지 않은 노드를 반환하거나 해당 위치에 새 노드를 반환할 수 있습니다. Edit()
는 지정되지 않은 순서로 노드를 반복합니다. 대체 노드가 대체된 Edit()
네트워크 노드를 참조하는 경우 최종 단계로 해당 교체에 대한 이러한 모든 참조를 업데이트합니다(즉, "올바른 작업 수행").
TODO: 예제입니다.
다음: 전체 함수 참조