         (assoc :input-gradient (util/empty-array [n-inputs]))))))
 
 (defn linear-layer
-  "Creates a linear layer with a new randomised weight matrix for the given number of inputs and outputs"
+  "Creates a linear layer with a new randomised weight matrix for the given number of inputs and outputs.
+
+   Options available:
+    :weights           = specify the weight matrix to use directly
+    :bias              = specify the bias vector to use directly
+    :l2-max-constraint = constraint to apply to l2 norm of rows (i.e. the vector of weights for each output)
+    :weight-scale      = factor to multiply the weights during initialisation (default 1.0)"
   ([n-inputs n-outputs & {:keys [weights bias l2-max-constraint] :as options}]
     (linear (or weights (util/weight-matrix n-outputs n-inputs))
             (or bias (util/empty-array [n-outputs]))

          [n-outputs n-inputs] (m/shape weights)
          n-outputs (long n-outputs)
          n-inputs (long n-inputs)]
      (when-not (== n-outputs (m/dimension-count bias 0)) (error "Mismatched weight and bias shapes"))
      (-> wm
        (assoc :weight-gradient (util/empty-array [n-outputs n-inputs]))


(defn linear
  "Constructs a weighted linear transformation module using a dense matrix and bias vector.
   Shape of input and output are determined by the weight matrix.

   Options available: 
    :l2-max-constraint = constraint to apply to l2 norm of rows (i.e. the vector of weights for each output)
    :weight-scale      = factor to multiply the weights during initialisation (default 1.0)"
  ([weights bias]
    (linear weights bias nil))
  ([weights bias options]
