å ¨ç·¨Swiftã§æ¸ããããªã¼ãã³ã½ã¼ã¹ã®äººå·¥ç¥è½ï¼æ©æ¢°å¦ç¿ã©ã¤ãã©ãªãåºã¦ãã¾ããããã®åããSwift-AIãã
ãã¢ãå
¥ã£ã¦ãã¦ããããªæãã§ææ¸ãæåèªèãã¦ããã¾ãï¼è©³ç´°ã¯å¾è¿°ãã¾ãï¼ã
ä»ã®ã¨ãã iOS 㨠OS X ããµãã¼ã ãã¦ããã¨ã®ãã¨ãMITã©ã¤ã»ã³ã¹ã
ã§ãããã¨
README ã® Features ãè¦ãã¨ã2016å¹´1æç¾å¨ããã£ã¼ããã©ã¯ã¼ãï¼é ä¼æåï¼ãã¥ã¼ã©ã«ãããã¯ã¼ã¯ã¨ãé«éè¡åæ¼ç®ã©ã¤ãã©ãªã¯ã§ãããã£ã¦ããããã§ãã
ããããããã¥ã¡ã³ããããã¾ãã
- https://github.com/collinhundley/Swift-AI/blob/master/Documentation/FFNN.md#multi-layer-feed-forward-neural-network
- https://github.com/collinhundley/Swift-AI/blob/master/Documentation/Matrix.md#matrix
ãã¯ãã«ã»è¡åæ¼ç®ã«ã¯ Accelerate Framework ãå©ç¨ãã¦ããã¨ã®ãã¨ã§ãããã©ã¼ãã³ã¹é¢ãèæ
®ããã¦ããã§ãã
ãã¢ã試ãã¦ã¿ã
å梱ããã¦ãããã¢ããã¸ã§ã¯ããSwift-AI-iOSããå®è¡ãã¦ã¿ãã¨ãä¸è¨ã®ããã«ãããµã¤ã³æ³¢ï¼sinï¼ã®ã°ã©ãããã£ã¦ããã¬ã¼ãã³ã°éå§ããã¨ãªã¬ã³ã¸ã®ç¹ã®éåããã®ãµã¤ã³æ³¢ã®ã°ã©ãã«è¿ã¥ãã¦ãããã¨ãããã®ã§ããã
ã»ã»ã»å¦ç¿ã®éç¨ãè¦è¦åãããã¢ãªã®ããããã¾ããããã¡ãã£ã¨ããããã¿ããããã«ãããªã¨ã
ã§ããã®Xcodeããã¸ã§ã¯ãã®ä¸ãè¦ã¦ã¿ãã¨ãHandwritingViewControllerãã¨ããã½ã¼ã¹ã³ã¼ããããã¾ããã
ãããææãæåèªèã®ãã¢ãããã®ããªã¨æã£ã¦ã½ã¼ã¹ã追ãããã¦ã¿ãã¨ãã©ãããä»ã«ããã¢ããããããããã¢ãèµ·åãã¦ç»é¢ãè¦ã¦ã¿ã¦ãããããã¨æãå·¦ä¸ã®Swiftçç»åãã¿ãããã¦ã¿ãã¨ã»ã»ã»
ãã³ãã¼ã¬ã¼ã¡ãã¥ã¼ãåºã¦ãã¾ããããªãã¨ããããã«ããUIãã
ã¾ãããã¯ããã§ã¯æ¬è³ªçãªåé¡ã§ã¯ãªãã®ã§ç½®ãã¨ãã¦ãHandwriting ã®ãã¢ã試ãã¦ã¿ãã¨ã
ãã·ãã¨ææ¸ãèªèãã¦ããã¾ããã
ææ¸ãæåèªèãã¢ã®å®è£
ã©ã¤ãã©ãªã®ä¸èº«ãèªãã§ããã¶ãç解ã§ããªãã®ã§ãããã¾ã§ã©ã¤ãã©ãªãå©ç¨ããå´ã¨ãã¦ããã¢ã§ã¯ã©ãå®è£
ãã¦ããã®ããHandwritingããã¢ã®ã½ã¼ã¹ãè¦ã¦ã¿ã¾ããã
ãã£ã¼ããã©ã¯ã¼ããã¥ã¼ã©ã«ãããã¯ã¼ã¯ï¼FFNNï¼ã®æºå
å¦ç¿æ¸ã¿ãã¼ã¿ã®ãã¡ã¤ã«ãæå®ãã¦ãFFNNã¯ã©ã¹ãåæåãã¾ãã
let url = NSBundle.mainBundle().URLForResource("handwriting-ffnn", withExtension: nil)! self.network = FFNN.fromFile(url)
ãã¥ã¼ã©ã«ãããã®æºåã¨ãã¦ã¯ããã ãã
ææ¸ãç»åã®é åãåãåºã
èªèããã¿ã¤ãã³ã°ã§ãããæ¬ãã¢ã§ã¯ `touchesEnded` ã¤ãã³ããæ¤åºãã¦ãã0.4s以å ã«æ¬¡ã® `touchesBegan` ããã㯠`touchesMoved` ãæ¤åºãããªããã°èªèå¦çãèµ°ãããã«å®è£ ããã¦ãã¾ãã
ã§ãææ¸ãç»åé åã®åãåºã㯠`scanImage()` ã¨ããã¡ã½ããã§è¡ããã¦ãã¾ãã
private func scanImage() -> [Float]? { var pixelsArray = [Float]() guard let image = self.handwritingView.canvas.image else { return nil } // Extract drawing from canvas and remove surrounding whitespace let croppedImage = self.cropImage(image, toRect: self.boundingBox!) // Scale character to max 20px in either dimension let scaledImage = self.scaleImageToSize(croppedImage, maxLength: 20) // Center character in 28x28 white box let character = self.addBorderToImage(scaledImage) self.handwritingView.imageView.image = character let pixelData = CGDataProviderCopyData(CGImageGetDataProvider(character.CGImage)) let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData) let bytesPerRow = CGImageGetBytesPerRow(character.CGImage) let bytesPerPixel = (CGImageGetBitsPerPixel(character.CGImage) / 8) var position = 0 for _ in 0..<Int(character.size.height) { for _ in 0..<Int(character.size.width) { let alpha = Float(data[position + 3]) pixelsArray.append(alpha / 255) position += bytesPerPixel } if position % bytesPerRow != 0 { position += (bytesPerRow - (position % bytesPerRow)) } } return pixelsArray }
ç»åãã¯ãããããããªãµã¤ãºããããã¨ãã£ãå¦çã¯æ¬ã©ã¤ãã©ãªãå©ç¨ããã«ããã£ã¦æ¬è³ªçãªé¨åã§ã¯ãªãã®ã§å²æãããã¨æã£ãã®ã§ãããããã¦è¼ããã®ã¯ããã®å¾ã®å¦çã«æ¸¡ãã«ããã£ã¦ãåºåãã¼ã¿ã®åãéè¦ã ã¨æã£ãããã§ãããã¤ã³ãã¨ãã¦ã¯ãRGBAã§ã¯ãªãA1ãã£ã³ãã«ã ããåãåºãã¦ãããã¨ï¼ææ¸ãæåèªèãªã®ã§è²æ
å ±ã¯å©ç¨ããªãï¼ã¨ãUIImageåã§ã¯ãªãFloatã®é
åã¨ãã¦ãã¯ã»ã«ãã¼ã¿ãè¿ãã¦ãããã¨ãã¨ãã£ããããã§ããããã
èªèå¦çã®å®è¡
ä¸è¿°ããå¦çã§åãåºããææ¸ãç»åæ å ±ï¼Floatã®é åï¼ãå¼æ°ã«æ¸¡ãã¦ãFFNNã¯ã©ã¹ã® `update` ã¡ã½ãããå®è¡ãã¾ãã
let output = try self.network.update(inputs: imageArray)
èªèçµæãåãåºã
å ã»ã©ã® `update` ã¡ã½ããã®è¿ãå¤ã§ãã Float ã®é åã¯ãæ°å0〜9ãé åã®ã¤ã³ããã¯ã¹ã¨ãã¦ãå¤ã«ã¯ Confidenceï¼ä¿¡é ¼åº¦ï¼ãã®æ°åã§ããå¯è½æ§ã®é«ãï¼ï¼ãå ¥ã£ã¦ããããã§ãã
ãªã®ã§ã次ã®ããã«ãæã Confidence ã®é«ãæ°åï¼ï¼èªèçµæï¼ãæ¢ãããã®èªèçµæã®æ°åã®å¤ã¨ãConfidenceãåãåºãã¦ãã¾ãã
private func outputToLabel(output: [Float]) -> (label: Int, confidence: Double)? { guard let max = output.maxElement() else { return nil } return (output.indexOf(max)!, Double(max / 1.0)) }
ãããã¦ã¿ã¦ã¿ãã¨ãå®è³ªçã«ã¯
- FFNNã¯ã©ã¹ã®åæå
- `update:` ã¡ã½ãããå¼ã¶
ãã®2ã¹ãããã ãã§ææ¸ãæåèªèãã§ãã¦ãããã¨ããããã¾ããé常ã«ç°¡åããã§ãã
èªåã®ããã¸ã§ã¯ãã¸ã®å°å ¥æ¹æ³
CocoaPodsãCarthageã¯ãµãã¼ããã¦ãªãã¨ã®ãã¨ã
Swift is open-source now, and it remains to be seen how these dependency managers will cooperate with other platforms.
ã¾ã 試ãã¦ãªãã§ããããã¢ããã¸ã§ã¯ããè¦ãéãã
- FFNN.swift
- Storage.swift
- FFNN+Storage.swift
ãããã®ãã¡ã¤ã«ã追å ããã°ä½¿ãããã§ãã
ä»ã«ãè¨å®ãããããããã¾ããããã¡ããã¨åããã¢ããã¸ã§ã¯ããç¨æããã¦ããã®ã§ãä½ãããã°ãã¡ãã¨æ¯è¼ãã¦ã¿ãã°ãããã¨ã
ææ
Swiftã§æ¸ããã¦ãã¦ãMITã©ã¤ã»ã³ã¹ãªãªã¼ãã³ã½ã¼ã¹ã§ãã¡ããã¨ããã©ã¼ãã³ã¹ãèæ ®ããã¦ãã¦ãç°¡åã«ä½¿ãããã¨ãããã¨ã§ããªãæå¾ ã®æã¦ãã©ã¤ãã©ãªã§ã¯ãªãã§ããããã
ä»å¾ããããªå¦ç¿æ¸ã¿ãã¼ã¿ãå¿ç¨äºä¾ãåºã¦ããã¨ããã«æ¥½ãããªãããã§ãã