     }
     
     func testTanhGradient() {
-        let eps:Double = 10e-6
+        let eps:Double = 10e-8
         let input = ConstantOp<D>(uniform(Extent(10)))
         let gradOutput = ConstantOp<D>(zeros(Extent(10)))
         

        XCTAssert(isClose(convOp.output, expected, eps:10e-4))
    }
    
    func testConvOpGradient1() {
        let eps = 10e-6
        let values = Tensor<D>([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        let input = ConstantOp(values)
        
        let convOp = Conv2dOp<D>(input: input, numFilters: 1, filterSize: Extent(3, 3))
        let convOpGrad = convOp.gradient() as! Conv2dGrad<D>
        
        let gradOutput = ConstantOp<D>(zeros(Extent(3, 3)))
        connect(from: gradOutput, to: convOpGrad, "gradOutput")
        
        let inputError = checkGradient(convOp, grad: convOpGrad, params: values, gradParams: convOpGrad.output, eps: eps)
        XCTAssertLessThan(inputError, eps)
    }
    
    func testConvOpGradient2() {
        let eps = 10e-6
        let values = Tensor<D>([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
        let input = ConstantOp(values)
        
        let convOp = Conv2dOp<D>(input: input, numFilters: 2, filterSize: Extent(3, 3))
        let convOpGrad = convOp.gradient() as! Conv2dGrad<D>
        
        let gradOutput = ConstantOp<D>(zeros(Extent(3, 3)))
        connect(from: gradOutput, to: convOpGrad, "gradOutput")
        
        let inputError = checkGradient(convOp, grad: convOpGrad, params: values, gradParams: convOpGrad.output, eps: eps)
        XCTAssertLessThan(inputError, eps)
    }
    
    func testMaxPoolingOp() {

        
        let tanhGrad = tanh.gradient() as! TanhGrad<D>
        connect(from: gradOutput, to: tanhGrad, "gradOutput")
        
        calcForwardGrad(tanh, params: input.output, eps: eps)
        
        // test gradient wrt the input
        let inputError = checkGradient(tanh, grad: tanhGrad, params: input.output, gradParams: tanhGrad.output, eps: eps)
