   CostFn
   (cost [this activation target]
     (let [a (mat/mul (mat/negate target) (log activation))
-          b (mat/mul (mat/sub 1.0 target) (log (mat/sub 1.0 a)))]
-      (mat/esum (mat/sub a b))))
+          b (mat/mul (mat/sub 1.0 target) (log (mat/sub 1.0 a)))
+          c (mat/esum (mat/sub a b))]
+      (println a)
+      (println b)
+      c))
 
   (delta [this activation z target]
     (mat/sub activation target)))


; TODO: switch to passing layer-specs that have size and activation fn
(defn network
  [layer-sizes]
  {:n-layers (count layer-sizes)
   :layer-sizes layer-sizes
   :biases (map rand-vector (next layer-sizes))
   :weights (map weight-matrix (rest layer-sizes) (drop-last layer-sizes))})

(defn feed-forward
  [{:keys [biases weights] :as net} input]

(deftype QuadraticCost []
  CostFn
  (cost [this activation target]
    ; NOTE: linear/norm is different for matrices and vectors so this row-matrix
    ; conversion is important for correctness.
    (let [diff (mat/sub activation target)
          diff (if (mat/vec? diff) (mat/row-matrix diff) diff)]
      (mat/mul 0.5 (mat/pow (linear/norm diff) 2))))

  (delta [this activation z target]
    (mat/emul (mat/sub activation target) (sigmoid-prime z))))
