다음을 통해 공유


BrainScript에서 모델 학습 어떻게 할까요?

계층별 학습

계층별 학습을 수행하려면 구성 파일에서 여러 "명령"을 사용하면 됩니다. 여기서 각 명령은 action=train 형식입니다.

command = TrainLayer1:TrainLayer2:TrainLayer3:EndToEndTrain:Test:Output

TrainLayer1= [ 
   action = train
   ...
]

TrainLayer2= [ 
   action = train
   ...
]
...

멀티태스킹 목표를 사용하여 학습

결합된 조건을 BrainScript 식으로 정의하고 개별 작업 손실을 다음으로 evaluationNodes지정하여 모니터링할 수 있습니다.

task1loss = CrossEntropyWithSoftMax(prediction,label)
task2loss = SquareError(reconstruction,input)
mtloss = task1loss + Constant(0.3) .* task2loss 
criterionNodes = (mtloss)
evaluationNodes = (task1loss:task2loss)

이미지에서 회귀 모델 학습

아래에서는 CNTK를 사용하여 입력 이미지에 대해 하나 이상의 부동 소수점 값을 예측하는 방법을 설명합니다. 예제 사용 사례는 지정된 이미지에 있는 개체의 경계 상자(예: x, y, w, h)를 예측하는 것입니다. 당신은 또한 단지 그 자동차의 이미지를보고 자동차의 가격을 예측 생각할 수 있습니다 (실제로 재미있을 것입니다). 여기서는 이미지의 평균 RGB 값([0, 1]으로 정규화됨)을 예측하기 위해 네트워크를 학습시키는 매우 간단한 예제를 사용합니다. 그러나 다른 사용 사례에도 동일한 단계가 적용됩니다. 해당 단계는 다음과 같습니다.

  1. 이미지와 기본 진리 회귀 레이블을 모두 네트워크에 대한 입력으로 정의
  2. 회귀 레이블과 일치하는 값 수를 예측하는 네트워크를 정의합니다.
  3. 예측된 값과 지상 진리를 비교하는 손실 함수 정의
  4. .cntk 구성 파일의 판독기 섹션을 조정하여 이미지 및 회귀 레이블을 모두 읽습니다.

여기에 당신이 그것을 할 수있는 방법입니다. 전체 구성 파일은 Examples/Image/Regression/RegrSimple_CIFAR10.cntk의 Examples 폴더에 포함되어 있습니다. 또한 이 폴더에는 이미지 데이터를 다운로드하고 학습 및 테스트를 위한 회귀 지상 진리를 생성하는 스크립트가 포함되어 있습니다.

1-3) 입력, 네트워크 및 손실 함수 정의:

    BrainScriptNetworkBuilder = [
        imageShape = 32:32:3
        featScale = Constant(1/256)
        labelDim = 3

        model (features) = {
            featNorm = Scale(features, featScale)
            h1 = LinearLayer {100,      init="gaussian", initValueScale=1.5} (featNorm)
            ol = LinearLayer {labelDim, init="gaussian", initValueScale=1.5} (h1)
        }.ol

        # inputs
        features = Input {imageShape}
        regrLabels = Input {labelDim}
        
        # apply model to features
        ol = model (features)

        # define regression loss
        # rmse = sqrt(SquareError(regrLabels, ol) / labelDim)
        sqerr = SquareError (regrLabels, ol)
        rmse = Sqrt (Constant(1/labelDim).* sqerr)

        featureNodes    = (features)
        labelNodes      = (regrLabels)
        criterionNodes  = (rmse)
        evaluationNodes = (rmse)
        OutputNodes     = (ol)
    ]
  1. ImageReader 및 CNTKTextFormatReader를 모두 사용하여 복합 판독기 정의:
    reader = {
        verbosity = 0 ; randomize = true
        deserializers = ({
            type = "ImageDeserializer" ; module = "ImageReader"
            file = "$dataDir$/cifar-10-batches-py/train_map.txt"
            input = {
                features = { transforms = (
                    { type = "Scale" ; width = 32 ; height = 32 ; channels = 3 ; interpolations = "linear" } :
                    { type = "Transpose" }
                )}
                ignored = { labelDim = 10 }
            }
        } : {
            type = "CNTKTextFormatDeserializer" ; module = "CNTKTextFormatReader"
            file = "$dataDir$/cifar-10-batches-py/train_regrLabels.txt"
            input = {
                regrLabels = { dim = 3 ; format = "dense" }
            }
        })
    }

판독기는 ImageReader를 사용하여 이미지를 읽고 CNTKTextFormatReader를 사용하여 회귀 접지 진리 레이블을 읽는 복합 판독기입니다. 이렇게 하려면 역직렬 변환기 배열을 정의하고(사용 {...} : {...}) 위의 네트워크에 정의된 대로 입력을 할당합니다(cf. 기능 및 regrLabels).

예제를 실행하려면 예제 /이미지/기타/CIFAR-10/06_RegressionSimple.cntk 를 참조하세요.

다중 레이블 분류자 학습

다중 레이블 분류의 경우 합계가 1인 입력 벡터만 처리할 수 있으므로 CrossEntropy를 사용하지 않아야 합니다. 합리적인 대안은 각 출력에 하나씩 로지스틱 손실 함수의 합계를 사용하는 것입니다.

...
probabilities = DenseLayer {outputSize, activation=Sigmoid} (hidden)
logisticLoss = Logistic (multiLabels, probabilities)
trainingCriterion = (logisticLoss)
...

손실 자체 외에도 잘못된 예측 수와 같은 다른 메트릭을 모니터링할 수 있습니다. 이에 대한 기본 제공 식은 없지만 다음과 같이 표현할 수 있습니다.

...
hammingLoss (y, p) = ReduceSum (y != (p > 0.5))
hl = hammingLoss(multiLabels,probabilities)
evaluationNodes = (hl)
...

이는 y[i]가 p[i]>0.5에 동의하지 않는 횟수를 계산합니다.

시퀀스 모델링 순서대로 시작

실습 랩에서는 CNTK 텍스트 형식과 같은 시퀀스 처리를 시작하기 위한 주요 요소와 다양한 입력 시퀀스에 짧은 별칭을 사용하도록 판독기를 구성하는 방법을 설명합니다. G2P(grapheme-to-phoneme) 예제는 실제 시퀀스 간 작업을 보여 줍니다.

시퀀스-시퀀스 모델링의 중요한 문제는 빔 검색을 사용하여 테스트 데이터를 디코딩하는 방법입니다. 이 작업은 최상위 작업이 "쓰기"인 구성의 섹션에서 수행할 수 있습니다. 디코딩하려면 가장 가능성이 큰 출력 시퀀스를 검색해야 합니다. CNTK에는 빔 검색 디코더가 있지만 다음과 같이 호출할 수 있습니다.

BrainScriptNetworkBuilder = (BS.Seq2Seq.BeamSearchSequenceDecoderFrom (
                                        BS.Network.Load (decodeModelPath), beamSize))

지정된 빔 크기로 빔 검색을 실행합니다. 빔 크기가 1인 경우 특수한 욕심 디코더가 있습니다.

BrainScriptNetworkBuilder = (BS.Seq2Seq.GreedySequenceDecoderFrom (
                                        BS.Network.Load (decodeModelPath)))

G2P 예제와 같이 두 디코더 모두 네트워크에 대한 특정 요구 사항이 있습니다.

DSSM(또는 나선형 DSSM) 모델 학습

DSSM (또는 심층 의미 체계 유사성 모델)은 관련 원본 및 대상 텍스트 쌍이 더 가까운 짧은 텍스트 포함 공간을 학습하기 위해 원본 대상 텍스트 쌍에 대해 학습된 DNN 모델입니다. 모델에 대한 텍스트 입력은 미리 계산된 trigram 해시로 표시됩니다(참조, Huang 등). C-DSSM의 경우 삼각 해시는 단어별로 계산된 다음 텍스트에서 단어가 발생하는 순서대로 연결됩니다. 두 모델에 대한 입력 크기는 고정된 크기입니다. 50K 삼각을 고려하면 원본 및 대상 텍스트에 해당하는 DSSM 입력은 각각 길이가 50K인 벡터입니다. C-DSSM의 경우 벡터는 길이가 50K x n이고, 여기서 첫 번째 n-1 단어 벡터가 연결되고 n번째 벡터에는 텍스트의 나머지 모든 단어에 해당하는 벡터의 합계가 포함됩니다. 텍스트에 1개 미만의 단어가 있는 경우 나머지 벡터는 0으로 채워집니다. 이미지와 비유를 그리려면 C-DSSM에 대한 텍스트 입력을 형식에 저장된 10x1 및 50K 채널 차원의 이미지로 [C x H x W] 생각할 수 있습니다.

이 예제에서는 CNTKTextFormatReader를 사용하여 DSSM/C-DSSM 모델을 학습하는 방법을 보여 줍니다. 데이터에는 2개의 기능(원본 및 대상 텍스트)과 1개의 레이블이 포함되어야 합니다(양수 샘플만 포함되므로 학습 데이터의 값 1로 항상 설정됨 - 학습 중에 부정 대상 예제는 임의 샘플링에 의해 생성됨). 판독기 구성은 다음과 같습니다.

reader = {
    verbosity   = 0
    randomize   = true

    deserializers = ({
        type    = "CNTKTextFormatDeserializer"
        module  = "CNTKTextFormatReader"
        file    = "data.txt"

        input = {
            Q   = { dim = 500000; format = "sparse" }
            D   = { dim = 500000; format = "sparse" }
            L   = { dim = 1;      format = "dense" }
        }
    })
}

입력 데이터의 샘플입니다.

|L 1 |Q 482:1 761:1 1832:1 2117:1 12370:1 17131:1 17854:1 24976:1 27676:1 28055:1 28177:1 29507:1|D 482:1 761:1 1832:1 2117:1 12370:1 17131:1 17854:1 24976:1 27676:1 28055:1 28177:1 29507:1
|L 1 |Q 149:1 153:1 595:1 671:1 675:1 1110:1 1517:1 2077:1 2114:1 5533:1 5662:1 6886:1 6901:1 7294:1 12846:1 13033:1 16614:1 19425:1 22015:1 24839:1 24994:1 26196:1 26358:1 27565:1|D 149:1 153:1 595:1 671:1 675:1 1110:1 1517:1 2077:1 2114:1 5533:1 5662:1 6886:1 6901:1 7294:1 12846:1 13033:1 16614:1 19425:1 22015:1 24839:1 24994:1 26196:1 26358:1 27565:1
|L 1 |Q 187:1 2294:1 2800:1 6920:1|D 187:1 2294:1 2800:1 6920:1

그리고 마지막으로 네트워크 정의,

BrainScriptNetworkBuilder = {
    # Constants scalars
    isConvolutional     = true
    numWords            = (if isConvolutional then 10 else 1)
    numTrigramsPerWord  = 50000
    numHiddenNodes      = 300
    wordWindowSize      = 3
    numWindows          = numWords - wordWindowSize + 1
    numNeg              = 50

    # Constant tensors
    CONST_GAMMA     = Constant(10)
    CONST_SHIFT     = Constant(1)
    CONST_NEG       = Constant(numNeg)
    CONST_PAD_NEG   = Constant(0, rows=numNeg, cols=1)
    CONST_PAD_POS   = Constant(1, rows=1, cols=1)
    CONST_PAD       = Splice(CONST_PAD_POS : CONST_PAD_NEG, axis=1)

    # Inputs
    Q   = Input(500000)
    D   = Input(500000)
    L   = Input(1)

    qr      = if isConvolutional
                then TransposeDimensions(ReshapeDimension(Q, 1, numTrigramsPerWord:1:numWords), 1, 3)
                else Slice(0, numTrigramsPerWord, Q, axis=1)
    dr      = if isConvolutional
                then TransposeDimensions(ReshapeDimension(D, 1, numTrigramsPerWord:1:numWords), 1, 3)
                else Slice(0, numTrigramsPerWord, D, axis=1)

    qdssm   = Sequential (
                DenseLayer {numHiddenNodes, activation=Tanh} :
                DenseLayer {numHiddenNodes, activation=Tanh} :
                DenseLayer {numHiddenNodes, activation=Tanh})
    qcdssm  = Sequential (
                ConvolutionalLayer {numHiddenNodes, (wordWindowSize:1), pad=false, activation=Tanh} :
                MaxPoolingLayer {(numWindows:1), stride=(1:1)} :
                DenseLayer {numHiddenNodes, activation=Tanh} :
                DenseLayer {numHiddenNodes, activation=Tanh})
    ddssm   = Sequential (
                DenseLayer {numHiddenNodes, activation=Tanh} :
                DenseLayer {numHiddenNodes, activation=Tanh} :
                DenseLayer {numHiddenNodes, activation=Tanh})
    dcdssm  = Sequential (
                ConvolutionalLayer {numHiddenNodes, (wordWindowSize:1), pad=false, activation=Tanh} :
                MaxPoolingLayer {(numWindows:1), stride=(1:1)} :
                DenseLayer {numHiddenNodes, activation=Tanh} :
                DenseLayer {numHiddenNodes, activation=Tanh})
    qembed  = if isConvolutional
                then qcdssm
                else qdssm
    dembed  = if isConvolutional
                then dcdssm
                else ddssm

    qf  = qembed(qr)
    df  = dembed(dr)
    lf  = Times(CONST_PAD, L)
    c   = CosDistanceWithNegativeSamples(qf, df, CONST_SHIFT, CONST_NEG)
    s   = Slice(0, 1, c, axis=1, tag="output")
    ce  = CrossEntropyWithSoftmax(lf, Scale(CONST_GAMMA, c), tag="criterion")
}

참고:

  • C-DSSM은 DSSM보다 지속적으로 더 나은 성능을 발휘하는 것으로 나타났지만 속도가 느려집니다(때로는 최대 5-10배 느림). 따라서 경우에 따라 더 많은 데이터(또는 더 많은 epoch)를 학습하여 동일한 학습 시간에 DSSM에서 더 나은 성능을 얻을 수 있습니다.
  • 원래 DSSM/C-DSSM은 쿼리 및 문서 제목 쌍에 대해 학습되었습니다. 그러나 세션 쿼리 쌍 또는 쿼리접미사 쌍과 같은 다른 종류의 데이터를 학습하여 짧은 텍스트 간의 다른 관계를 배울 수 있습니다.

디컨볼루션 및 풀링을 사용하여 이미지 자동 인코더 학습

여기에 지침이 있습니다.

빠른 R CNN을 사용하여 개체 검색 학습

여기에 지침이 있습니다.