2016-11-10 20 views
6

Khung Shader hiệu suất kim loại cung cấp hỗ trợ cho việc xây dựng Lưới thần kinh liên kết của riêng bạn. Khi tạo ví dụ MSPCNNConvolution, nó đòi hỏi một nửa trọng lượng 4D như thông số init được biểu diễn dưới dạng con trỏ nổi 1D.Thứ tự trọng lượng MPSCNN

init(device: MTLDevice, 
    convolutionDescriptor: MPSCNNConvolutionDescriptor, 
    kernelWeights: UnsafePointer<Float>, 
    biasTerms: UnsafePointer<Float>?, 
    flags: MPSCNNConvolutionFlags) 

Các tài liệu có này để nói về tensor 4D

Cách bố trí của trọng lượng lọc được bố trí sao cho nó có thể được giải thích lại như một tensor 4D (mảng) cân [outputChannels] [kernelHeight] [kernelWidth] [inputChannels/groups]

Thật không may là thông tin không thực sự cho tôi biết cách sắp xếp mảng 4D thành một chiều Float con trỏ.

Tôi đã thử đặt hàng các trọng số như đối tác BNNS yêu cầu nó, nhưng không có may mắn.

Làm cách nào để đại diện cho bộ tạo 4D (mảng) như một con trỏ 1D Float (mảng)?

PS: Tôi đã cố gắng sắp xếp nó như một mảng C và đưa con trỏ đến mảng phẳng, nhưng nó không hoạt động.

CẬP NHẬT

@RhythmicFistman: Đó là cách tôi lưu trữ nó trong một mảng đơn giản, mà tôi có thể chuyển đổi sang một UsafePointer<Float> (nhưng không hoạt động):

var output = Array<Float>(repeating: 0, count: weights.count) 

for o in 0..<outputChannels { 
    for ky in 0..<kernelHeight { 
     for kx in 0..<kernelWidth { 
      for i in 0..<inputChannels { 
       let offset = ((o * kernelHeight + ky) * kernelWidth + kx) * inputChannels + i 
       output[offset] = ... 
      } 
     } 
    } 
} 
+0

bạn có thể cho biết cách bạn thực hiện nỗ lực 4D đến 1D không?chặn bằng cách sử dụng con trỏ sai, tôi nghĩ rằng điều duy nhất có thể đi sai là thứ tự của các chỉ số. –

+0

@RhythmicFistman Đã cập nhật câu hỏi, vấn đề không phải là ngay cả dự án ví dụ của OWS của Apple (với trọng số được đào tạo của riêng họ) hoạt động chính xác. Vì vậy, làm thế nào tôi phải biết whats thậm chí sai ... dữ liệu của tôi hoặc thực hiện của họ. –

+0

Bạn đang đề cập đến mẫu Apple nào? Cả hai MetalImageRecognition và MPSCNNHelloWorld dường như làm việc cho tôi với Xcode 8.2 beta và iOS 10.2 beta. – warrenm

Trả lời

1

Ok vì vậy tôi tìm ra. Dưới đây là các chức năng python 2 tôi sử dụng để cải cách nhiều nếp cuộn của tôi và ma trận kết nối đầy đủ

# shape required for MPSCNN [oC kH kW iC] 
# tensorflow order is [kH kW iC oC] 
def convshape(a): 
    a = np.swapaxes(a, 2, 3) 
    a = np.swapaxes(a, 1, 2) 
    a = np.swapaxes(a, 0, 1) 
    return a 

# fully connected only requires a x/y swap 
def fullshape(a): 
    a = np.swapaxes(a, 0, 1) 
    return a 
1

Đây là điều mà thời gian gần đây tôi phải làm cho trọng lượng Caffe, vì vậy tôi có thể cung cấp việc thực hiện Swift cho làm thế nào tôi sắp xếp lại những. Hàm sau sẽ lấy một mảng Float của các trọng lượng Caffin cho một convolution (theo thứ tự [c_o] [c_i] [h] [w]) và sắp xếp lại những gì mà Metal mong đợi ([c_o] [h] [w] [c_i] đơn đặt hàng):

public func convertCaffeWeightsToMPS(_ weights:[Float], kernelSize:(width:Int, height:Int), inputChannels:Int, outputChannels:Int, groups:Int) -> [Float] { 

    var weightArray:[Float] = Array(repeating:0.0, count:weights.count) 
    var outputIndex = 0 

    let groupedInputChannels = inputChannels/groups 
    let outputChannelWidth = groupedInputChannels * kernelSize.width * kernelSize.height 

    // MPS ordering: [c_o][h][w][c_i] 
    for outputChannel in 0..<outputChannels { 
     for heightInKernel in 0..<kernelSize.height { 
      for widthInKernel in 0..<kernelSize.width { 
       for inputChannel in 0..<groupedInputChannels { 
        // Caffe ordering: [c_o][c_i][h][w] 
        let calculatedIndex = outputChannel * outputChannelWidth + inputChannel * kernelSize.width * kernelSize.height + heightInKernel * kernelSize.width + widthInKernel 
        weightArray[outputIndex] = weights[calculatedIndex] 
        outputIndex += 1 
       } 
      } 
     } 
    } 

    return weightArray 
} 

Dựa trên hình ảnh lớp của tôi, điều này dường như tạo ra kết quả chập đúng (phù hợp với sản phẩm của Caffe). Tôi tin rằng nó cũng đúng cách nhóm vào tài khoản, nhưng tôi cần phải xác minh điều đó.

Dòng chảy có thứ tự khác với Caffein, nhưng bạn sẽ có thể thay đổi toán trong phần bên trong của vòng lặp để tính toán điều đó.

1

Tài liệu ở đây giả định một số chuyên môn trong C. Trong bối cảnh đó, [x] [y] [z] thường được thu gọn thành mảng 1-d khi x, y và z là hằng số được biết tại thời gian biên dịch. Khi điều này xảy ra, thành phần z thay đổi nhanh nhất, theo sau là y, theo sau là x - bên ngoài.

Nếu chúng ta có [2] [2] [2], nó bị thu gọn thành 1D là:

{ a[0][0][0], a[0][0][1], a[0][1][0], a[0][1][1], 
    a[1][0][0], a[1][0][1], a[1][1][0], a[1][1][1] } 
Các vấn đề liên quan