ç§ã¯èšäºãèªãã®ã奜ãã§ã¯ãããŸãããããã«GitHubã«è¡ããŸã
ãã®ãäžäŸ¿ããããããŠç³ãèš³ããããŸããã
ãã®èšäºã§èª¬æããããšã¯ãäœããã®åœ¢ã§ã³ã³ãã¥ãŒã¿ãŒãµã€ãšã³ã¹ã®ããã€ãã®åéã«åœ±é¿ãäžããŸãããåã
ã®é åã«é£ã³èŸŒãããšã¯ã§ããŸããã ãã®ãäžäŸ¿ããããããŠç³ãèš³ããããŸããã
2017幎ã«ã¯ãããããæ©æ¢°åŠç¿ãšäººå·¥ç¥èœã«ã€ããŠè©±ãå¿ èŠã¯ãããŸããã ãžã£ãŒããªã¹ãã£ãã¯ãªèšäºãšæ·±å»ãªç§åŠè«æã®äž¡æ¹ãããã®äž»é¡ã«é¢ããŠãã§ã«å€æ°æžãããŠããŸãã ãããã£ãŠãèªè ã¯ãã§ã«ãããäœã§ããããç¥ã£ãŠãããšæ³å®ãããŸãã æ©æ¢°åŠç¿ãšããã°ãããŒã¿ãµã€ãšã³ãã£ã¹ããšãœãããŠã§ã¢ãšã³ãžãã¢ã®ã³ãã¥ããã£ã¯ãéåžžããã£ãŒããã¥ãŒã©ã«ãããã¯ãŒã¯ãæ瀺ããŠããããã®ããã©ãŒãã³ã¹ã®ããã«éåžžã«äººæ°ããããŸãã çŸåšãäžçã«ã¯äººå·¥ãã¥ãŒã©ã«ãããã¯ãŒã¯ã®åé¡ã解決ããããã®ããŸããŸãªãœãããŠã§ã¢ãœãªã¥ãŒã·ã§ã³ãšè€åäœãå€æ°ãããŸããCaffeãTensorFlowãTorchãTheanoïŒripïŒãcuDNNãªã©ã§ãã
ã¹ã€ãã
Swiftã¯é©æ°çãªããããã³ã«æåã®ãªãŒãã³ãœãŒã¹ããã°ã©ãã³ã°èšèªã§ãã¯ãªã¹ã©ãããŒïŒæè¿SpaceXã®åŸã«Appleãé¢ããŠGoogleã«èœã¡çããïŒã«ãã£ãŠAppleã®å£ã®äžã§æé·ããŸããã
Appleã®OSã«ã¯ããããªãã¯ã¹ãšãã¯ãã«ä»£æ°ãæäœããããã®ããŸããŸãªã©ã€ãã©ãªãæ¢ã«ãããŸãããBLASãBNNSãDSPã¯ã1ã€ã®Accelerateã©ã€ãã©ãªã®å±æ ¹ã®äžã§çµåãããŸããã
2015幎ãã°ã©ãã£ãã¯ãã¯ãããžãŒMetalã«åºã¥ãæ°åŠã®å®è£ ã®ããã®å°ããªãœãªã¥ãŒã·ã§ã³ãç»å ŽããŸããã
CoreMLã¯2016幎ã«ç»å ŽããŸããïŒ
CoreMLã¯ãæ¢è£œã®ãã¬ãŒãã³ã°æžã¿ã¢ãã«ïŒCaffeV1ãKerasãscikit-learnïŒãã€ã³ããŒãããéçºè ã«ãããã¢ããªã±ãŒã·ã§ã³ã«ãšã¯ã¹ããŒãããæ©äŒãæäŸã§ããŸãã
ã€ãŸãã次ã®ããšãè¡ãå¿ èŠããããŸãããµãŒãããŒãã£ã®ãã¬ãŒã ã¯ãŒã¯ã䜿çšããŠãPythonãŸãã¯C ++ã®å¥ã®ãã©ãããã©ãŒã ã§ã¢ãã«ãæ§ç¯ããŸãã 次ã«ããµãŒãããŒãã£ã®ããŒããŠã§ã¢ãœãªã¥ãŒã·ã§ã³ã§ãã¬ãŒãã³ã°ããŸãã
ãããŠãã®åŸã®ã¿ãSwiftèšèªã§ã€ã³ããŒãããŠäœæ¥ã§ããŸãã ç§ã®æèŠã§ã¯ãããã¯éåžžã«æ··éããŠããŠå°é£ã§ãã
ãã³ãœã«ãããŒ
TensorFlowã¯ã人工ãã¥ãŒã©ã«ãããã¯ãŒã¯ãå®è£ ããä»ã®ãœãããŠã§ã¢ããã±ãŒãžãšåæ§ã«ããã¥ãŒãã³ããããã®é¢ä¿ããšã©ãŒèšç®ããšã©ãŒéååžãæäœããããã®å€ãã®æ¢è£œã®æœè±¡åãšã¡ã«ããºã ãåããŠããŸãã ããããä»ã®ããã±ãŒãžãšã¯ç°ãªãããžã§ããã£ãŒã³ïŒGoogleåŸæ¥å¡ãåæ£ãã¡ã€ã«ã·ã¹ãã ã®äœæè ãTensorFlowããã³ä»ã®å€ãã®åªãããœãªã¥ãŒã·ã§ã³ïŒã¯ãããŒã¿å®è¡ã¢ãã«ãšããŒã¿å®è¡ããã»ã¹ãåé¢ãããšããã¢ã€ãã¢ãTensorFlowã«çµã¿èŸŒãããšã«ããŸããã ããã¯ãæåã«ããããèšç®ã°ã©ããèšè¿°ãããã®èšç®ãéå§ããåŸã«ã®ã¿æå³ãããšããããšã§ãã ãã®ã¢ãããŒãã«ãããããŒã¿å®è¡ã¢ãã«ãåé¢ããéåžžã«æè»ã«ããŒã¿å®è¡ããã»ã¹ãšçŽæ¥é£æºããŠãç°ãªãããŒãïŒããã»ããµããããªã«ãŒããã³ã³ãã¥ãŒã¿ãŒãã¯ã©ã¹ã¿ãŒïŒã«å®è¡ãåæ£ã§ããŸãã
TensorFlowKit
1ã€ã®èšèªã®ãã¬ãŒã ã¯ãŒã¯å ã§ãã¢ãã«éçºããæçµã¢ããªã±ãŒã·ã§ã³ã§ã®ã¢ãã«éçºãŸã§ã®ã¿ã¹ã¯ã®ãµã€ã¯ã«å šäœã解決ããããã«ãTensorFlowã䜿çšããã¢ã¯ã»ã¹ããã³äœæ¥ã€ã³ã¿ãŒãã§ã€ã¹ãäœæããŸããã
ãœãªã¥ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ã¯ãäžã¬ãã«ãšé«ã¬ãã«ã®2ã€ã®ã¬ãã«ã®ããã«èŠããŸãã
- äœã¬ãã«Cã§ã¯ããã®ã¢ãžã¥ãŒã«ã䜿çšãããšãè¿ éãªèšèªããlibtensorflowã«ã¢ã¯ã»ã¹ã§ããŸãã
- äžéã¬ãã«ã§ã¯ãCãã€ã³ã¿ãŒããé¢ããŠãçŸãããã¹ãã§æäœããããšãã§ããŸãã
- é«ã¬ãã«ã§ã¯ãã¢ãã«èŠçŽ ã«ã¢ã¯ã»ã¹ããããã®ããŸããŸãªæœè±¡åãšãã°ã©ãããšã¯ã¹ããŒããã€ã³ããŒããèŠèŠåããããã®ããŸããŸãªãŠãŒãã£ãªãã£ãå®è£ ããŸãã
ãããã£ãŠãè¿ éãªèšèªã§ã¢ãã«ïŒèšç®ã®ã°ã©ãïŒãäœæããè€æ°ã®ãããªã«ãŒãã䜿çšããŠUbuntu OSãå®è¡ãããµãŒããŒã§ã¢ãã«ããã¬ãŒãã³ã°ããmacOSãŸãã¯tv OSã®ããã°ã©ã ã§ç°¡åã«éãããšãã§ããŸãã éçºã¯ããã®é·æãšçæããã¹ãŠåããéåžžã®Xcodeã§å®è¡ã§ããŸãã
ããã¥ã¡ã³ããšAPIã¯ãã®ãªã³ã¯ã«ãããŸãã
ãã¥ãŒã©ã«ãããã¯ãŒã¯ã®çè«ã«ã€ããŠç°¡åã«èª¬æããŸãã
人工ãã¥ãŒã©ã«ãããã¯ãŒã¯ã¯ãç¥çµç³»ã®çµç¹ã«ããããã¥ãŒãã³æ¥ç¶ã®ç¹å®ã®ïŒéåžžã«åçŽåãããïŒã¢ãã«ãå®è£
ããŸãã 倧ããªæ¬¡å
ã®ãã¯ãã«ã®åœ¢åŒã®å
¥åä¿¡å·ã¯ããã¥ãŒãã³ã§æ§æãããå
¥åå±€ã«å°éããŸãã 次ã«ãåå
¥åãã¥ãŒãã³ã¯ãã®ä¿¡å·ã次ã®å±€ã«éä¿¡ãããã¥ãŒãã³éã®æ¥ç¶ã®ç¹æ§ïŒéã¿ïŒãšåŸç¶ã®å±€ã®ãã¥ãŒãã³ã®ç¹æ§ã«åºã¥ããŠä¿¡å·ãå€æããŸãã ãã¬ãŒãã³ã°äžãåºåä¿¡å·ãåºåå±€ã§åœ¢æãããäºæ³ããããã®ãšæ¯èŒãããŸãã åºåä¿¡å·ãšãµã³ãã«ä¿¡å·ã®å·®ã«åºã¥ããŠããšã©ãŒå€ãçæãããŸãã ããã«ããã®èª€å·®ã䜿çšããŠãããããåŸé
ïŒãã¥ãŒãã³éã®æ¥ç¶ãä¿®æ£ããå¿
èŠãããæ¹åã®ãã¯ãã«ïŒãèšç®ããŸããããã«ãããå°æ¥ããã¥ãŒã©ã«ãããã¯ãŒã¯ãäºæ³ãããä¿¡å·ã«é¡äŒŒããä¿¡å·ãçæããŸãã ããã»ã¹èªäœã¯ãéãšã©ãŒååžãŸãã¯éäŒæãšåŒã°ããŸãã ãããã£ãŠããã¥ãŒãã³ãšãã¥ãŒãã³éã®æ¥ç¶ã¯ããã®ãã¥ãŒã©ã«ãããã¯ãŒã¯ãåŠç¿ããŠããããŒã¿ã¢ãã«ã®ç¹æ§ãäžè¬åããããã«å¿
èŠãªæ
å ±ãèç©ããŸãã æè¡çãªå®è£
ã¯ãBLASãLAPACKãDSPãªã©ã®ãœãªã¥ãŒã·ã§ã³ã«ãã£ãŠããçšåºŠãŸã§æ¢ã«å®è£
ãããŠããè¡åãšãã¯ãã«ã®ããŸããŸãªæ°åŠæŒç®ã«åºã¥ããŠããŸãã
ããã¹ã
äŸãšããŠããHello worldïŒãããã¥ãŒã©ã«ãããã¯ãŒã¯ã®äžçã§åãäžããŸãã ãç»åMNISTãåé¡ããåé¡ã§ãã MNISTããŒã¿ã»ããã¯ãæ°åã®28 x 28ãã¯ã»ã«ã®ææžãæ°å€ç»åã§ãã ãããã£ãŠããã¬ãŒãã³ã°çšã®60,000åã®ç»åãšãã¹ãçšã®10,000åã®ç»åã«ãã¡ããšåæ£ããã10åã®ã¯ã©ã¹ããããŸãã ç§ãã¡ã®ã¿ã¹ã¯ã¯ãç»åãåé¡ãã10ã®ã¯ã©ã¹ã®ããããã«å±ããããå€æã§ãããã¥ãŒã©ã«ãããã¯ãŒã¯ãäœæããããšã§ãã
TensorFlowKitèªäœã䜿çšããåã«ãTensorFlowãã€ã³ã¹ããŒã«ããå¿ èŠããããŸãã macOSã§ã¯ãbrew package managerã䜿çšã§ããŸãã
brew install libtensorflow
Linuxçšã®ãã«ãã¯ãã¡ãããå ¥æã§ããŸãã
è¿ éãªãããžã§ã¯ããäœæããäŸåé¢ä¿ãããã«æ¥ç¶ããŸã
dependencies: [ .package(url: "https://github.com/Octadero/TensorFlow.git", from: "0.0.7") ]
MNISTããŒã¿ã»ããã®æºåã
MNISTããŒã¿ã»ãããæäœããããã®ããã±ãŒãžãäœæãããŠããããã¡ãããå ¥æã§ããŸãã ãã®ããã±ãŒãžã¯ãããŒã¿ã»ãããåå¥ã«äžæãã£ã¬ã¯ããªã«ããŠã³ããŒãããå±éããŠæ¢æã®ã¯ã©ã¹ãšããŠæ瀺ããŸãã
dataset = MNISTDataset(callback: { (error: Error?) in print("Ready") })
å¿ èŠãªæäœã®ã°ã©ããåéããŸãã
èšç®ã°ã©ãã®ç©ºéå šäœãšéšå空éã¯ã¹ã³ãŒããšåŒã°ããç¬èªã®ååãæã€å ŽåããããŸãã
ãããã¯ãŒã¯ã®å ¥åã§ã2ã€ã®ãã¯ãã«ããã£ãŒãããŸãã 1ã€ç®ã¯ãé«æ¬¡å 784ïŒ28x28 pxïŒã®ãã¯ãã«ã®åœ¢åŒã§è¡šç€ºãããåçã§ãã
ã€ãŸãããã¯ãã«xã®åã³ã³ããŒãã³ãã«ã¯ããã¯ãã£å ã®ãã¯ã»ã«ã®è²ã«å¯Ÿå¿ãã0ã1ã®Floatå€ããããŸãã
2çªç®ã®ãã¯ãã«ã¯ã察å¿ãã1ã€ã®ã³ã³ããŒãã³ããã¯ã©ã¹çªå·ã«å¯Ÿå¿ãã圢åŒïŒä»¥äžãåç §ïŒã§æå·åããã察å¿ããã¯ã©ã¹ã«ãªããŸãã ãã®äŸã§ã¯ãã¯ã©ã¹ã¯2ã§ã
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0 ]
å ¥åãã©ã¡ãŒã¿ãŒã¯ãã¬ãŒãã³ã°ããã»ã¹äžã«å€æŽããããããããããåç §ããããã®ãã¬ãŒã¹ãã«ããŒãäœæããŸãã
//Input sub scope let inputScope = scope.subScope(namespace: "input") let x = try inputScope.placeholder(operationName: "x-input", dtype: Float.self, shape: Shape.dimensions(value: [-1, 784])) let yLabels = try inputScope.placeholder(operationName: "y-input", dtype: Float.self, shape: Shape.dimensions(value: [-1, 10]))
ã°ã©ããèŠèŠåããããã«ã TensorBoardã䜿çšããŸãã ã TensorFlowKitã䜿çšããŠã°ã©ããäœæããåŠç¿ããã»ã¹ãèŠèŠåããæ¹æ³ã«ã€ããŠã¯ãå¥ã®èšäºã§èª¬æããŸãã
[ å ¥å ]åã§ã¯ã次ã®ããã«ãªããŸãã
ãããå ¥åã¬ã€ã€ãŒã§ãã
次ã«ãå ¥åã¬ã€ã€ãŒãšé衚瀺ã¬ã€ã€ãŒã®éã«ãŠã§ã€ãïŒçµåïŒãäœæããŸãã
let weights = try weightVariable(at: scope, name: "weights", shape: Shape.dimensions(value: [784, 10])) let bias = try biasVariable(at: scope, name: "biases", shape: Shape.dimensions(value: [10]))
ãããã¯ãŒã¯ã®ãã¬ãŒãã³ã°äžã«éã¿ãšããŒã¹ãå€æŽãããïŒèª¿æŽãããïŒãããã°ã©ãã«å€æ°æŒç®ãäœæããŸãã
ãããŠããŒãã§æºãããããã³ãœã«ã§ããããåæåããŸãã
次ã«ãæãåçŽãªæäœïŒx * WïŒ+ bãå®è¡ããé衚瀺ã¬ã€ã€ãŒãäœæããŸã
ããã¯ã ãã¯ãã« xïŒæ¬¡å 1x784ïŒ ã«è¡å WïŒæ¬¡å 784x10ïŒãä¹ç®ããåºåºãè¿œå ããæäœã§ãã
ãã®äŸã§ã¯ãé ãå±€ã¯ãã§ã«åºåïŒãHello WorldïŒãã¬ãã«ã®ã¿ã¹ã¯ïŒã§ãããããåºåä¿¡å·ãåæããŠåè ãéžæããå¿ èŠããããŸãã ãããè¡ãã«ã¯ãsoftmaxæäœã䜿çšããŸãã
以äžã§èª¬æããå 容ãããããç解ããããã«ããã¥ãŒã©ã«ãããã¯ãŒã¯ãè€éãªæ©èœãšèŠãªãããšãææ¡ããŸãã é¢æ°ã®å ¥åã§ããã¯ãã«xïŒç»åãè¡šãïŒãåãåããŸãã åºåã§ã¯ãé¢æ°ãå ¥åãã¯ãã«ãåã¯ã©ã¹ã«å±ããããšãã©ã®çšåºŠç¢ºä¿¡ããŠããã®ãã瀺ããã¯ãã«ãååŸããŸãã
次ã«ãåã¯ã©ã¹ã§ååŸãããäºæž¬ã®å€§ããã®èªç¶å¯Ÿæ°ãååŸãããããæ£ããã¯ã©ã¹ã®ãã¯ãã«ã®å€ã§ä¹ç®ããŸããããã¯ãæåã«ãã¡ããšéä¿¡ãããŸãïŒyLabelïŒã
ãããã£ãŠããšã©ãŒå€ãååŸããããã䜿çšããŠãã¥ãŒã©ã«ãããã¯ãŒã¯ããéé£ãã§ããŸãã 以äžã«2ã€ã®äŸã瀺ããŸãã æåã®ã¯ã©ã¹2ïŒãšã©ãŒã¯2.3ã2çªç®ã®ã¯ã©ã¹1ïŒãšã©ãŒã¯ãŒãã§ãã
let log = try scope.log(operationName: "Log", x: softmax) let mul = try scope.mul(operationName: "Mul", x: yLabels, y: log) let reductionIndices = try scope.addConst(tensor: Tensor(dimensions: [1], values: [Int(1)]), as: "reduction_indices").defaultOutput let sum = try scope.sum(operationName: "Sum", input: mul, reductionIndices: reductionIndices, keepDims: false, tidx: Int32.self) let neg = try scope.neg(operationName: "Neg", x: sum) let meanReductionIndices = try scope.addConst(tensor: Tensor(dimensions: [1], values: [Int(0)]), as: "mean_reduction_indices").defaultOutput let cross_entropy = try scope.mean(operationName: "Mean", input: neg, reductionIndices: meanReductionIndices, keepDims: false, tidx: Int32.self)
次ã«äœãããïŒ
æ°åŠçã«ã¯ãç®çé¢æ°ãæå°åããå¿ èŠããããŸãã 1ã€ã®ã¢ãããŒãã¯ãåŸé éäžæ³ã§ãã å¿ èŠã«å¿ããŠã次ã®èšäºã§åœŒã«ã€ããŠè©±ãããšããŸãã
ãããã£ãŠãéã¿ïŒè¡åWã®æåïŒãšåºåºãã¯ãã«bã®ãããããã©ã®çšåºŠä¿®æ£ããå¿ èŠãããããèšç®ããå¿ èŠããããŸããããã«ããããã¥ãŒã©ã«ãããã¯ãŒã¯ã¯ãã®ãããªå ¥åããŒã¿ã®èª€å·®ãå°ããããŸãã
æ°åŠçã«ã¯ããã¹ãŠã®äžéããŒãã®å€ã«ãã£ãŠåºåããŒãã®åå°é¢æ°ãèŠã€ããå¿ èŠããããŸãã çµæã®ã·ã³ããªãã¯ã°ã©ãã£ãšã³ãã«ãããå€æ°Wããã³bã®åã³ã³ããŒãã³ãã®å€ãããããã®ãããããåã®èšç®ã®çµæã«ã©ã®ããã«åœ±é¿ãããã«åŸã£ãŠãã·ãããã§ããŸãã
TensorFlowã®éæ³ã
å®éããããã®è€éãªèšç®ã®ãã¹ãŠïŒ å®éã«ã¯ããŸã ãã¹ãŠã§ã¯ãããŸãã ïŒããTensorFlowã¯ãäœæããã°ã©ããåæããããšã§ç¬ç«ããŠå®è¡ã§ããŸãã
let gradientsOutputs = try scope.addGradients(yOutputs: [cross_entropy], xOutputs: [weights.variable, bias.variable])
ãã®æäœãåŒã³åºããåŸãTensorFlowã¯ããã«50åã®æäœãåå¥ã«æ§ç¯ããŸãã
ããã§ãå ã»ã©åŸé éäžæ³ã§èšç®ããå€ã«éã¿ã®æŽæ°æäœãè¿œå ããã ãã§ååã§ãã
let _ = try scope.applyGradientDescent(operationName: "applyGradientDescent_W", `var`: weights.variable, alpha: learningRate, delta: gradientsOutputs[0], useLocking: false)
ããã ãã§ããã«ãŠã³ãã®æºåãã§ããŸããïŒ
å ã»ã©èšã£ãããã«ãTensorFlowã¯ã¢ãã«ãšèšç®ãåé¢ããŸãã ãããã£ãŠãäœæããã°ã©ãã¯èšç®ãå®è¡ããããã®ã¢ãã«ã«ãããŸããã
Sessionã䜿çšããŠèšç®ãå®è¡ã§ããŸãã
ããŒã¿ã»ããããããŒã¿ãæºåãããããããã³ãœã«ã«é 眮ããããã»ãã·ã§ã³ãéå§ããŸãã
guard let dataset = dataset else { throw MNISTTestsError.datasetNotReady } guard let images = dataset.files(for: .image(stride: .train)).first as? MNISTImagesFile else { throw MNISTTestsError.datasetNotReady } guard let labels = dataset.files(for: .label(stride: .train)).first as? MNISTLabelsFile else { throw MNISTTestsError.datasetNotReady } let xTensorInput = try Tensor(dimensions: [bach, 784], values: xs) let yTensorInput = try Tensor(dimensions: [bach, 10], values: ys)
for index in 0..<1000 { let resultOutput = try session.run(inputs: [x, y], values: [xTensorInput, yTensorInput], outputs: [loss, applyGradW, applyGradB], targetOperations: []) if index % 100 == 0 { let lossTensor = resultOutput[0] let gradWTensor = resultOutput[1] let gradBTensor = resultOutput[2] let wValues: [Float] = try gradWTensor.pullCollection() let bValues: [Float] = try gradBTensor.pullCollection() let lossValues: [Float] = try lossTensor.pullCollection() guard let lossValue = lossValues.first else { continue } print("\(index) loss: ", lossValue) lossValueResult = lossValue print("w max: \(wValues.max()!) min: \(wValues.min()!) b max: \(bValues.max()!) min: \(bValues.min()!)") } }
ãã®ã³ãŒãã¯GitHubã«ãããŸã ã
100åã®æäœããšã«ããšã©ãŒã®ãµã€ãºãæšæž¬ããŸãã
æ°ããèšäºïŒ TensorFlowKitã䜿çšãããã¥ãŒã©ã«ãããã¯ãŒã¯ã®åŠç¿ããã»ã¹ã®èŠèŠåãå ¬éãããŸããã